如何将接口方法的返回类型定义为另一个接口?

我是接口和抽象类的新手。 我想创建几个接口来定义购物车系统对象的核心方法和变量。 然后我想创建实现核心function的抽象类。 这个想法是,其他类可以以不同的方式用于不同的项目。

这是我的(简化)界面:

public interface ICart { ... List CartItems { get; set; } } public interface ICartItem { int ProductId { get; set; } int Quantity { get; set; } } 

这是我的抽象Cart类(再次,只显示相关的行)实现ICart:

 public abstract class Cart : ICart { private List _cartItems = new List(); public List CartItems { get { return _cartItems; } } } 

我的CartItem类实现了ICartItem:

 public abstract class CartItem : ICartItem { ... } 

当我尝试编译类时,我得到一个错误说:’Cart’没有实现接口成员’CartItems’。 ‘Cart.CartItems’无法实现’ICart.CartItems’,因为它没有匹配的返回类型System.Collections.Generic.List 。

我认为这里的想法是接口可以由许多类实现,这些类以不同的方式执行核心function并添加新方法等。为什么我的接口需要知道实际使用的是什么类,同样长因为该类实际上正确地实现了接口?

您需要在C#2中使用generics来实现:

 public interface ICart where T : ICartItem { // ... List CartItems { get; set; } } public abstract class Cart : ICart { // ... public List CartItems { get; set; } } 

在抽象类中,您应该定义CartItems属性的返回类型,类型为List

但是,如果你真的想要属性是List类型,你可以这样做:

 public interface ICart where TCartItem : ICartItem { List CartItems { get; set; } } public interface ICartItem { } public abstract class Cart : ICart { public List { get; set; } } public abstract class CartItem : ICartItem { } 

这是对立/协方差的问题。

进行此编译需要进行2次更改。

1)删除界面属性上的“set”选项。 (它只实现了get;属性,无论如何都是最有意义的)

2)将购物车更改为:

公共抽象类购物车:ICart
 { 

 private List _cartItems = new List(); public List CartItems { ... 

我还强烈建议您更改界面以公开IList而不是List。 设计指南(和FxCop)建议不要在公共接口中公开List。 List是一个实现细节–IList是适当的接口/返回类型。

界面是一种协议。 如果您愿意,您和使用您class级的任何人之间的合同。 通过告诉大家你正在实现ICart接口,你向他们保证接口中的所有方法都存在于你的类中。 因此,所有方法都必须与接口方法的签名匹配。

为了返回实现 ICartItem的项目列表,您需要使用DrJokepu建议的generics。 这告诉大家,界面只能实现一个实现ICartItem的对象列表,而不是ICartItem。

 public interface ICart where T : ICartItem { List CartItems { get; set; } } 

ICart为CartItems指定了一个getter和setter,但是你的实现只有一个get。

有两种方法可以实现这一目标。 您可以使用generics或显式实现接口成员。

generics

 public interface ICart where TCartItem : ICartItem { ... List CartItems { get; set; } } public interface ICartItem { int ProductId { get; set; } int Quantity { get; set; } } public abstract class Cart : ICart { private List _cartItems = new List(); public List CartItems { get { return _cartItems; } } } public abstract class CartItem : ICartItem { ... } 

明确实施的成员

 public interface ICart { ... List CartItems { get; set; } } public interface ICartItem { int ProductId { get; set; } int Quantity { get; set; } } public abstract class Cart : ICart { private List _cartItems = new List(); List ICart.CartItems { get { return CartItems; } } public List CartItems { get { return _cartItems; } } } public abstract class CartItem : ICartItem { ... }