Mar*_*ram 3 .net c# generics covariance
我的构建中出现错误,其中说:
错误12无法将类型'System.Collections.Generic.IEnumerator <BaseClass>'隐式转换为'System.Collections.Generic.IEnumerator <IParentClass>'.存在显式转换(您是否错过了演员?)
简单地把它扔掉是不对的?
这是我的代码:
public Dictionary<Int32, BaseClass> Map { get; private set; }
public IEnumerator<BaseClass> GetEnumerator()
{
return this.Map.Values.GetEnumerator();
}
public IEnumerator<IParentClass> IEnumerable<IParentClass>.GetEnumerator()
{
return this.GetEnumerator(); // ERROR!
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,我可以改变这一行:
return this.GetEnumerator();
Run Code Online (Sandbox Code Playgroud)
至:
return (IEnumerator<IParentClass>)this.GetEnumerator();
Run Code Online (Sandbox Code Playgroud)
(没有任何不良副作用)?
一般承认的答案:
我已将功能更改为以下内容(阅读Jon Skeet的帖子后):
IEnumerator<IParentClass> IEnumerable<IParentClass>.GetEnumerator()
{
return this.Map.Values.Cast<IParentClass>().GetEnumerator();
}
Run Code Online (Sandbox Code Playgroud)
不,你不能,因为仿制品目前在C#中并不协变..NET本身有一些支持(对于委托和接口)但它尚未真正使用.
如果您返回IEnumerable<BaseClass>而不是IEnumerator<BaseClass>(并假设.NEt 3.5)您可以使用Enumerable.Cast- 但您目前需要编写自己的扩展方法,例如
public static IEnumerator<TParent> Upcast<TParent, TChild>
(this IEnumerator<TChild> source)
where TChild : TParent
{
while (source.MoveNext())
{
yield return source.Current;
}
}
Run Code Online (Sandbox Code Playgroud)
或者在您的情况下,您可以使用之前的Cast:
return this.Map.Values.Cast<BaseClass>().GetEnumerator();
Run Code Online (Sandbox Code Playgroud)