C# 使用泛型接口属性实现接口时,请使用兼容的具体类型
有时,您希望实现如下所示的接口:C# 使用泛型接口属性实现接口时,请使用兼容的具体类型,c#,class,generics,interface,C#,Class,Generics,Interface,有时,您希望实现如下所示的接口: public interface ITraversable<T> { List<T> Children { get; } } public interface ITraversable<T> { ObservableCollection<T> Children { get; } } public接口不可用{ 列出子项{get;} } 但有时您需要一个不同的集合类,如下所示: publi
public interface ITraversable<T> {
List<T> Children { get; }
}
public interface ITraversable<T> {
ObservableCollection<T> Children { get; }
}
public接口不可用{
列出子项{get;}
}
但有时您需要一个不同的集合类,如下所示:
public interface ITraversable<T> {
List<T> Children { get; }
}
public interface ITraversable<T> {
ObservableCollection<T> Children { get; }
}
public接口不可用{
可观察收集子项{get;}
}
但您不想重复自己的操作,因此请尝试以下界面:
public interface ITraversable<T> {
IEnumerable<T> Children { get; }
}
public接口不可用{
IEnumerable子项{get;}
}
但是任何使用List或ObservableCollection的实现类都会得到一个错误:
错误CS0738“Tester”未实现接口成员“ITraversable.Children”Tester.Children无法实现“ITraversable.Children”,因为它没有匹配的返回类型“IEnumerable”
是否可以创建一个具有泛型接口属性的接口,该属性可由多个具体类实现使用?这是我发现的一种方法,可以使用可由多个具体类实现的泛型接口实现单个接口:
public interface ITraversable<T, out TEnumerable> where TEnumerable : IEnumerable<T> {
TEnumerable Children { get; }
}
公共接口ITraversable其中TEnumerable:IEnumerable{
可数子项{get;}
}
这允许您拥有使用IEnumerable的不同具体实现的不同类
public class TestClass1 : ITraversable<TestClass1, List<TestClass1>> {
public List<TestClass1> Children { get; }
}
public class TestClass2 : ITraversable<TestClass2, ObservableCollection<TestClass2>> {
public ObservableCollection<TestClass2> Children { get; }
}
公共类TestClass1:ITraversable{
公共列表子项{get;}
}
公共类TestClass2:ITraversable{
公共可观察集合子项{get;}
}
实现接口时,类型必须完全匹配。这就是为什么不能将IEnumerable替换为List,因为它们不是完全相同的类型。但是,如果将确切类型指定为接口上的泛型参数,则可以精确匹配这些类型。这是我发现的一种方法,可以使用可由多个具体类实现的泛型接口实现单个接口:
public interface ITraversable<T, out TEnumerable> where TEnumerable : IEnumerable<T> {
TEnumerable Children { get; }
}
公共接口ITraversable其中TEnumerable:IEnumerable{
可数子项{get;}
}
这允许您拥有使用IEnumerable的不同具体实现的不同类
public class TestClass1 : ITraversable<TestClass1, List<TestClass1>> {
public List<TestClass1> Children { get; }
}
public class TestClass2 : ITraversable<TestClass2, ObservableCollection<TestClass2>> {
public ObservableCollection<TestClass2> Children { get; }
}
公共类TestClass1:ITraversable{
公共列表子项{get;}
}
公共类TestClass2:ITraversable{
公共可观察集合子项{get;}
}
实现接口时,类型必须完全匹配。这就是为什么不能将IEnumerable替换为List,因为它们不是完全相同的类型。但是,如果将确切类型指定为接口上的通用参数,则可以精确匹配这些类型。您可以使用显式接口实现,同时仍具有
IEnumerable
要求:
public interface ITraversable<T> {
IEnumerable<T> Children { get; }
}
public class Implementer1<T>: ITraversable<T> {
List<T> Children { get; }
IEnumerable<T> ITraversable<T>.Children => Children;
}
public class Implementer2<T>: ITraversable<T> {
ObservableCollection<T> Children { get; }
IEnumerable<T> ITraversable<T>.Children => Children;
}
public接口不可用{
IEnumerable子项{get;}
}
公共类实现者1:可撤销{
列出子项{get;}
IEnumerable.Children=>Children;
}
公共类实现器2:可撤销{
可观察收集子项{get;}
IEnumerable.Children=>Children;
}
这不会产生两个同名属性的错误,也不会导致无限递归,因为显式接口实现是隐藏的,除非您通过接口访问它。您可以使用显式接口实现,同时仍然具有
IEnumerable
要求:
public interface ITraversable<T> {
IEnumerable<T> Children { get; }
}
public class Implementer1<T>: ITraversable<T> {
List<T> Children { get; }
IEnumerable<T> ITraversable<T>.Children => Children;
}
public class Implementer2<T>: ITraversable<T> {
ObservableCollection<T> Children { get; }
IEnumerable<T> ITraversable<T>.Children => Children;
}
public接口不可用{
IEnumerable子项{get;}
}
公共类实现者1:可撤销{
列出子项{get;}
IEnumerable.Children=>Children;
}
公共类实现器2:可撤销{
可观察收集子项{get;}
IEnumerable.Children=>Children;
}
这不会导致有两个同名属性的错误,也不会导致无限递归,因为显式接口实现是隐藏的,除非您通过接口访问它。我更喜欢扫掠器的原因是,虽然这会使它编译,现在,所有使用
ITraversable
接口的操作都需要将第二个泛型类型参数定义为IEnumerable
。因此,您的代码将充满这样的内容ITraversable input
,而不是能够使用ITraversable input
。从您自己的问题“具有泛型接口属性”,但您将该接口更改为现在需要多个泛型类型参数。我更喜欢扫掠器的原因是,虽然这会使其编译,现在,所有使用ITraversable
接口的操作都需要将第二个泛型类型参数定义为IEnumerable
。因此,您的代码将充满这样的内容ITraversable input
,而不是能够使用ITraversable input
。从您自己的问题“具有泛型接口属性”,但您将该接口更改为现在需要多个泛型类型参数