根据CSharp语言规范。
接口定义了一个可以由类和结构实现的契约。接口不提供它定义的成员的实现-它只是指定必须由实现接口的类或结构提供的成员。
所以我有一个:
interface ITest
{
IEnumerable<int> Integers { get; set; }
}
我的意思是。“我与属性有一个契约,作为可以枚举的整数集合”。
然后,我需要以下接口实现:
class Test : ITest
{
public List<int> Integers { get; set; }
}
我得到以下编译器错误:
'Test‘不实现接口成员'ITest.Integers’。'Test.Integers‘不能实现'ITest.Integers’,因为它没有匹配的返回类型‘System.Collection tions.Generic.IEnDigable’。
只要我可以说,我的Test类实现了ITest契约,因为int属性列表实际上是int的IEnumerable。
那么c#编译器是如何告诉我错误的呢?
发布于 2011-11-03 06:06:16
您不能这样做,因为如果允许的话,您将面临一个很大的问题,这取决于实现。考虑:
interface ITest
{
IEnumerable<int> Integers { get; set; }
}
class Test : ITest
{
// if this were allowed....
public List<int> Integers { get; set; }
}
这将允许:
ITest test = new Test();
test.Integers = new HashSet<int>();
这将使用于测试的合同无效,因为Test说它包含List<int>
。
现在,可以使用显式接口实现来满足这两个签名,这取决于它是从ITest
引用还是从Test
引用调用的:
class Test : ITest
{
// satisfies interface explicitly when called from ITest reference
IEnumerable<int> ITest.Integers
{
get
{
return this.Integers;
}
set
{
this.Integers = new List<int>(value);
}
}
// allows you to go directly to List<int> when used from reference of type Test
public List<int> Integers { get; set; }
}
发布于 2011-11-03 06:45:49
FYI,您想要的特性称为“虚拟方法返回类型协方差”,正如您已经发现的,C#不支持它。它是其他面向对象语言的一个特性,比如C++。
虽然我们经常收到对这个特性的请求,但是我们没有计划将它添加到语言中。这不是一个可怕的特点,如果我们有它,我会使用它。但是我们有很多不这样做的理由,包括它没有得到CLR的支持,它为可修改的组件添加了新的有趣的故障模式,Anders并不认为它是一个非常有趣的特性,而且我们有很多很多更高的优先级和有限的预算。
顺便说一句,尽管人们一直要求我们使用虚拟方法返回类型协方差,但从来没有人要求虚拟方法形式参数类型反方差,尽管从逻辑上讲,它们本质上是相同的特征。也就是说,我有一个使用长颈鹿的虚拟方法/接口方法M,我想用一个带有动物的方法M来覆盖/实现它。
发布于 2011-11-03 06:05:36
简单的事实是,如果一个接口显示:
IInterface{
Animal A { get; }
}
然后,该属性的实现必须与类型完全匹配,完全是。试图将其实现为
MyClass : IInterface{
Duck A { get; }
}
不起作用--即使Duck
是Animal
相反,您可以这样做:
MyClass : IInterface{
Duck A { get; }
Animal IInterface.A { get { return A; } }
}
即提供IInterface.A
成员的显式实现,利用Duck
和Animal
之间的类型关系。
在您的例子中,这意味着实现getter (至少是ITest.Integers )
IEnumerable<int> ITest.Integers { get { return Integers; } }
要实现setter,您需要对输入值进行乐观的转换或使用.ToList()。
注意,在这些显式实现中使用A
和Integers
不是递归的,因为显式接口实现隐藏在类型的公共视图中--只有当调用者通过它的IInterface
/ITest
接口实现与该类型对话时,它们才会启动。
https://stackoverflow.com/questions/7996127
复制相似问题