首页 > 解决方案 > 我可以使用接口来定义基本期望吗?

问题描述

我有一组与两个大型遗留项目中(几乎)匹配的数据结构配对的模型;每个项目都位于 API 的任一侧,因此我想创建一个可以被两者继承的“全局”项目,以确保某种形式的一致性,减少发生火灾的可能性并开始执行接口而不是实现的编程。

我的计划是使用接口来创建一种可以继承但可以稍微偏离的共同点(由于一侧需要数据但另一侧不需要数据)但是我遇到了以这种方式使用它们的问题说到嵌套。

假设我有两个接口:

namespace Example.Interfaces
{
    public interface A
    {
        int X { get; set; }
        int Y { get; set; }
    }

    public interface B
    {
        int J { get; set; }
        List<A> KLM { get; set; }
    }
}

如果我想在模型中使用这些,我会考虑做类似下面的事情。

namespace Example.Models
{
    public class Item : A
    {
        int X { get; set; }
        int Y { get; set; }
    }

    public class Container : B
    {
        int J { get; set; }
        List<Item> KLM { get; set; } // Wrong
    }
}

这就是我的期望被证明是完全错误的点(坏derpasaurus,回学校去!)

在上面的例子中。在Container我希望能够定义 a List<>of Items (如图所示),因为它们继承A; 这显然不是这种情况,因为我看到警告告诉我应该定义KLMList<Interfaces.A>.

如果我进行了 Visual Studio 推荐的更改,我将无法Item为 field分配 type KLM,如下所示。

var derp = new Container
{
    J = 1
    KLM = new List<Item> { X = 123, Y = 456 }
};

然后我看到以下错误

无法将类型“Example.Models.Item”隐式转换为“Example.Interfaces.A”

我的问题是:

标签: c#interface

解决方案


要使其工作,您需要更改界面:

public interface B<T> where T:A
{
    int J { get; set; }
    List<T> KLM { get; set; }
}

在这里,你的接口条件强制实现它的类具有 A 类型的对象列表。

现在您的接口可以由您的类实现:

public class Container : B<Item>
{
   public int J { get; set; }
   public List<Item> KLM { get; set; } 
}

如果您想在不知道具体类型的情况下对接口进行读取访问,B您可以修改:

public interface B
{
    int J { get; set; }
    IEnumerable<A> KLM { get; }
}

public interface B<T> : B where T:A
{
    new List<T> KLM { get; set; }
}

和实施:

public class Container : B<Item>
{
   public int J { get; set; }
   public List<Item> KLM { get; set; } 

   IEnumerable<A> B.KLM => KLM;
}

推荐阅读