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;} } 我的

在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;}
}
我的问题是:是否有某种软件哲学使这种类型的实现出错?这是一个有争议的范例,有点像多重继承,争论已经发生了几十年


我看不出为什么这样的接口实现不能很好地工作。如果您知道
ITest
,那么您只能看到
CTest.Numbers
IEnumerable
部分。如果您了解
CTest
,则可以使用整个
列表
实现。既然
List
源于
IEnumerable
,为什么它不能满足接口要求?

调用重写基方法时子类返回子类型的能力

在这种情况下,由于
Numbers
属性的setter,您的示例是不安全的:

ITest t = new CTest();
t.Numbers = new HashSet<int>();
接口就是合同。它准确地告诉客户端哪些方法/属性可用,以及输入和输出的类型

当您告诉客户机,任何实现了
ITest
的类都将接受any
IEnumerable
作为
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); } 
    }

}