为什么不能从受约束的通用集合中推断出接口?
作者:互联网
我有一段这样的代码:
public IEnumerable<ICacheMember> Flubvert( IEnumerable<ICacheMember> members )
{
// do some stuff to members
return members;
}
但是我对为什么不能这样做感到困惑:
public IEnumerable<T> ExecuteFlubversion<T>( IEnumerable<T> memberList ) where T: class,ICacheMember
{
return Flubvert( memberList );
}
当然,对泛型的约束应该保证memberList是ICacheMembertype的IEnumerable?我真的需要将现有(但隐式)ICacheMember对象的集合转换为显式ICacheMember对象,然后再将其转换回吗?我可以理解,鉴于Flubvert的方法签名,我可能需要将它们转换回去,但是我不明白为什么我必须在方法调用中转换它们.这是我在工作代码中所做的工作,但似乎与泛型的一般优雅行为完全不符,因此,我认为我一定会对这种操作方式有所误解.
解决方法:
首先,IEnumerable< out T>的协方差为0. (和其他通用类型)仅在T是引用类型时有效,因此您需要:
public IEnumerable<ICacheMember> ExecuteFlubversion<T>(IEnumerable<T> memberList)
where T: class, ICacheMember // NOTE 'class'
{
var flub = Flubvert(memberList); // can you call with 'memberList'?
return flub; // can you return that type?
// depending on what 'Flubvert' does, maybe return 'IEnumerable<T>'
// and say:
// return (IEnumerable<T>)flub;
}
另请注意,我更改了返回值. C#编译器不能保证非通用Flubvert方法返回的对象比IEnumerable< ICacheMember>更具体.
标签:generics,covariance,contravariance,c 来源: https://codeday.me/bug/20191028/1954782.html