我有两个类GenericList
和SpecificList
,其中SpecificList
继承自GenericList
。 GenericList
实施IEnumerable<GenericItem>
和SpecificList
实施IEnumerable<SpecificItem>
。 SpecificItem
继承自GenericItem
。我必须在GetEnumerator
和GenericList
中实施SpecificList
,因为它们会实施IEnumerable<T>
。在GenericList
中,这很容易,我只返回基础List<T>
的枚举器:
public IEnumerator<GenericItem> GetEnumerator()
{
return genericItemsList.GetEnumerator();
}
然而,在SpecificList
中,它似乎更棘手。将IEnumerator<GenericItem>
投射到IEnumerator<SpecificItem>
似乎有风险,我不知道这是否有效。相反,我做了以下事情:
public new IEnumerator<SpecificItem> GetEnumerator()
{
IEnumerator<GenericItem> enumerator = base.GetEnumerator();
while (enumerator.MoveNext())
{
yield return (SpecificItem)enumerator.Current;
}
}
这编译很好,一个简单的MSTest单元测试调用SpecificList.GetEnumerator()
似乎表明它有效。但是,ReSharper在上述方法中突出显示base
,并出现以下警告:
通过匿名方法,lambda表达式,查询表达式或迭代器中的'base'关键字访问GenericList.GetEnumerator会导致无法验证的代码
这是我应该担心的吗?我应该采取不同的做法吗?
编辑:我正在使用ReSharper 5.1完整版预发布版本5.1.1715.35。
另外,我应该暂停运行MSTest单元测试:我只需按 Ctrl + R , Ctrl + T 在Chrome中重新加载页面...
答案 0 :(得分:6)
R#是正确的,在3.0版本的C#编译器中访问迭代器/ lambda中的base
关键字可能导致无法验证的代码。当它有或没有时有点复杂,我不会试图在这里覆盖它。
解决此问题的最简单方法是在另一个非静态私有方法中包含对base.GetEnumerator
的调用,并从迭代器中引用该方法。
private IEnumerator<GenericItem> GetBaseEnumerator() {
return base.GetEnumerator();
}
public new IEnumerator<SpecificItem> GetEnumerator()
{
IEnumerator<GenericItem> enumerator = GetBaseEnumerator();
while (enumerator.MoveNext())
{
yield return (SpecificItem)enumerator.Current;
}
}
我很确定这个错误是在C#编译器的4.0版本中修复的。
答案 1 :(得分:0)
将
IEnumerator<GenericItem>
投射到IEnumerator<SpecificItem>
似乎有风险,我不知道这是否有效。
当然可以。
return base.Cast<SpecificItem>().GetEnumerator();
没有比当前实施更多或更少的风险。事实上,我很确定它或多或少是相同的代码。