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

时间:2009-03-16 14:29:29

标签: c# interface

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

以下是我的(简化)界面:

public interface ICart
{
    ...
    List<ICartItem> CartItems { get; set; }
}

public interface ICartItem
{
    int ProductId { get; set; }
    int Quantity { get; set; }
}

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

public abstract class Cart : ICart
{

    private List<CartItem> _cartItems = new List<CartItem>();

    public List<CartItem> CartItems 
    {
        get
        {
            return _cartItems;
        }
    }
}

我的CartItem类实现了ICartItem:

public abstract class CartItem : ICartItem
{
    ...
}

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

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

6 个答案:

答案 0 :(得分:20)

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

public interface ICart<T> where T : ICartItem
{
    // ...
    List<T> CartItems { get; set; }
}

public abstract class Cart : ICart<CartItem>
{
    // ...
    public List<CartItem> CartItems { get; set; }
}

答案 1 :(得分:4)

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

但是,如果你真的希望属性类型为List<CartItem>,你可以这样做:

public interface ICart<TCartItem> where TCartItem : ICartItem
{
   List<TCartItem> CartItems { get; set; }
}

public interface ICartItem
{
}

public abstract class Cart : ICart<CartItem>
{
     public List<CartItem> { get; set; }
}

public abstract class CartItem : ICartItem
{
}

答案 2 :(得分:3)

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

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

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

2)将购物车更改为:

public abstract class Cart : ICart
{

private List<CartItem> _cartItems = new List<CartItem>();

public List<ICartItem> CartItems 
{ ...

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

答案 3 :(得分:2)

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

泛型

public interface ICart<TCartItem> where TCartItem : ICartItem
{
    ...
    List<TCartItem> CartItems { get; set; }
}

public interface ICartItem
{
    int ProductId { get; set; }
    int Quantity { get; set; }
}

public abstract class Cart : ICart<CartItem>
{

    private List<CartItem> _cartItems = new List<CartItem>();

    public List<CartItem> CartItems 
    {
        get
        {
            return _cartItems;
        }
    }
}
public abstract class CartItem : ICartItem
{
    ...
}

明确实施的成员

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

public abstract class Cart : ICart
{
    private List<CartItem> _cartItems = new List<CartItem>();

    List<ICartItem> ICart.CartItems
    {
       get
       {
           return CartItems;
       }
    }
    public List<CartItem> CartItems 
    {
        get
        {
            return _cartItems;
        }
    }
}
public abstract class CartItem : ICartItem
{
    ...
}