如何声明和使用通用接口(请参阅命名空间Sample2)以与命名空间Sample1中的类相同的方式工作?
我知道有一种解决方法(请参阅命名空间Sample2Modified),但这不是我想要实现的。
使用类时,这很好用:
namespace Sample1
{
public class ClassContainer<T1, T2>
where T1 : T2
{ }
public class ClassParent
{ }
public class ClassChild : ClassParent
{ }
public class ClassSampleDoesWork<TItem>
where TItem : ClassParent
{
ClassContainer<IEnumerable<TItem>, IEnumerable<ClassParent>> SomeProperty { get; set; }
}
}
但是,对于接口,编译器在ClassSampleDoesNotWork中声明属性时会发出此警告:
Error 16 The type 'System.Collections.Generic.IEnumerable<TItem>'
cannot be used as type parameter 'T1' in the generic type or method
'Sample2.IInterfaceContainer<T1,T2>'. There is no implicit reference
conversion from 'System.Collections.Generic.IEnumerable<TItem>' to
'System.Collections.Generic.IEnumerable<Sample2.IInterfaceParent>'.
代码:
namespace Sample2
{
public interface IInterfaceContainer<T1, T2>
where T1 : T2
{ }
public interface IInterfaceParent
{ }
public interface IInterfaceChild : IInterfaceParent
{ }
public class ClassSampleDoesNotWork<TItem>
where TItem : IInterfaceParent
{
IInterfaceContainer<IEnumerable<TItem>, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
}
}
如果我修改类以使用TEnumerableOfItem而不是TItem,它可以工作:
namespace Sample2Modified
{
public interface IInterfaceContainer<T1, T2>
where T1 : T2
{ }
public interface IInterfaceParent
{ }
public interface IInterfaceChild : IInterfaceParent
{ }
public class ClassSampleModifiedDoesWork<TEnumerableOfItem>
where TEnumerableOfItem : IEnumerable<IInterfaceParent>
{
IInterfaceContainer<TEnumerableOfItem, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
}
}
答案 0 :(得分:5)
尝试将class
约束添加到TItem
:
namespace Sample2
{
public interface IInterfaceContainer<T1, T2>
where T1 : T2
{ }
public interface IInterfaceParent
{ }
public interface IInterfaceChild : IInterfaceParent
{ }
public class ClassSampleDoesNotWork<TItem>
where TItem : class, IInterfaceParent
{
IInterfaceContainer<IEnumerable<TItem>, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
}
}
这是有效的,因为方差仅适用于引用类型(或存在标识转换)。除非您添加TItem
,否则不知道: class
是引用类型。
有关更多信息,请阅读this文章。
以下是演示此行为的示例代码:
IEnumerable<Object> items = new List<int>(); // Compiler error.