我有一组模型,它们与两个大型旧项目中的(几乎)匹配的数据结构配对。每个项目都位于API的任一侧,因此我想创建一个“ Globals”项目,这两个项目都可以继承,以确保某种形式的一致性,减少发生火灾的可能性,并开始对接口而非实现实施编程。
我的计划是使用接口创建一种可以继承但可以略有偏离的通用基础(由于一方面需要数据,而另一侧则不需要),但是我遇到了使用它们的问题以这种方式进行嵌套。
说我有两个界面:
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
}
}
在这一点上,我的期望被证明是完全错误的(糟糕的derapasaurus,回到学校!)
在上面的示例中。在Container
中,我希望能够定义List<>
个Item
(如图所示),因为它们继承了A
;显然不是这样,因为我看到警告告诉我应该将KLM
定义为List<Interfaces.A>
。
如果我进行了Visual Studio建议的更改,则无法对字段Item
进行类型KLM
的分配,如下所示。
var derp = new Container
{
J = 1
KLM = new List<Item> { X = 123, Y = 456 }
};
然后我看到以下错误
无法将类型'Example.Models.Item'隐式转换为'Example.Interfaces.A'
我的问题是:
Item
隐式转换为A
而导致的潜在数据丢失,这是不可能的吗?答案 0 :(得分:3)
要使其正常工作,您需要更改界面:
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;
}