C# 接口实现原理
在C#中,不允许实现如下接口:C# 接口实现原理,c#,interface,C#,Interface,在C#中,不允许实现如下接口: public interface ITest { IEnumerable<int> Numbers { get; set; } } public class CTest : ITest { public List<int> Numbers { get; set; } } 公共接口测试 { IEnumerable number{get;set;} } 公共类测试:ITest { 公共列表编号{get;set;} } 我的
public interface ITest
{
IEnumerable<int> Numbers { get; set; }
}
public class CTest : ITest
{
public List<int> Numbers { get; set; }
}
公共接口测试
{
IEnumerable number{get;set;}
}
公共类测试:ITest
{
公共列表编号{get;set;}
}
我的问题是:是否有某种软件哲学使这种类型的实现出错?这是一个有争议的范例,有点像多重继承,争论已经发生了几十年
我看不出为什么这样的接口实现不能很好地工作。如果您知道
ITest
,那么您只能看到CTest.Numbers
的IEnumerable
部分。如果您了解CTest
,则可以使用整个列表
实现。既然List
源于IEnumerable
,为什么它不能满足接口要求?调用重写基方法时子类返回子类型的能力
在这种情况下,由于Numbers
属性的setter,您的示例是不安全的:
ITest t = new CTest();
t.Numbers = new HashSet<int>();
接口就是合同。它准确地告诉客户端哪些方法/属性可用,以及输入和输出的类型
当您告诉客户机,任何实现了ITest
的类都将接受anyIEnumerable
作为number
的值,但是CTest
类只接受列表
时,您违反了该约定
如果您想要实现接口,但同时还公开更具体的集合类型,您可以显式地实现接口,但是您必须决定要做的是,客户端尝试“设置”一个不是列表的IEnumerable
,一个选项就是在幕后创建一个列表
:
public class CTest : ITest
{
public List<int> Numbers { get; set; }
// satisfies the interface
IEnumerable<int> ITest.Numbers {
get { return Numbers; }
set { Numbers = new List<int>(value); }
}
}
公共类CTest:ITest
{
公共列表编号{get;set;}
//满足接口
IEnumerable测试数{
获取{返回数字;}
设置{Numbers=新列表(值);}
}
}
现在,知道CTest
的客户端可以使用List
属性,但是只知道接口的客户端仍然可以设置集合而不强制转换
public class CTest : ITest
{
public List<int> Numbers { get; set; }
// satisfies the interface
IEnumerable<int> ITest.Numbers {
get { return Numbers; }
set { Numbers = new List<int>(value); }
}
}