我需要一些建议/帮助,我再也看不到树上的木头了.
这是一系列直接使用泛型实现某些接口的类.
然后我试图抛出具体类型,例如:
MyGenericObject<SomeObject> _obj;
IMyGenericObject<ISomeObject> _genObj = (IMyGenericObject<ISomeObject>)_obj;
Run Code Online (Sandbox Code Playgroud)
//无效的演员表
我读过一些关于协方差和逆变的文章,但不太清楚为什么这不可能,或者如何绕过它呢?
所以,在这个例子中:
public interface IMyObject<in T> where T : IBaseObject
{
T Activity { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
不会工作......
....因为,你无法获取并设置Activity属性.
在这个例子中,我需要做:
public interface IMyObject<out T> where T : IBaseObject
{
T Activity { get; }
}
Run Code Online (Sandbox Code Playgroud)
希望对某人有所帮助,并感谢所有人的帮助!
pho*_*oog 11
如果将接口声明为具有covariant(out)参数,则只能这样做.只有在协变使用参数时才能执行此操作.
例如,如果接口IMyGenericObject<T>具有接受T参数的方法,则会阻止您将参数声明为协变.相反,如果有一个返回a的方法,则会T阻止您将参数声明为逆变.
编辑
在回应你对SLaks答案的评论时,我很想重复Eric Lippert所写的关于共同和逆变的所有内容.请参阅http://blogs.msdn.com/b/ericlippert/archive/tags/Covariance+and+Contravariance/以及他在SO中的答案(最近/sf/answers/586614941/)
总结一下:
你不能转发IList<string>,IList<object>因为将a传递给a 是合法FileInfo的IList<object>,但将它传递给a 是不合法的IList<string>.
您不能将an转换IList<object>为an IList<string>,因为从a检索项IList<string>并将其分配给字符串引用是合法的,但是IList<object>可能包含FileInfo,而不能将其分配给字符串引用.
编辑2
既然您需要建议,也可以将接口拆分为共变和逆变部分.要继续列表示例,您可以拥有这些接口
public interface ICovariantList<out T>
{
T this[int index] { get; }
//...
}
public interface IContravariantList<in T>
{
T this[int index] { set; }
void Add(T item);
//...
}
public class SomeList<T> : ICovariantList<T>, IContravariantList<T>
{
//...
}
Run Code Online (Sandbox Code Playgroud)
这允许您根据上下文协同或逆转地使用该类.
您需要将接口声明为具有covariant(out)泛型参数.