【问题标题】:accessing C# base class in iterator causes ReSharper warning在迭代器中访问 C# 基类会导致 ReSharper 警告
【发布时间】:2011-03-09 08:17:05
【问题描述】:

我有两个类,GenericListSpecificList,其中SpecificList 继承自GenericListGenericList 实现 IEnumerable<GenericItem>SpecificList 实现 IEnumerable<SpecificItem>SpecificItem 继承自 GenericItem。我必须在GenericListSpecificList 中实现GetEnumerator,因为它们实现了IEnumerable<T>。在GenericList 中,很简单,我只返回底层List<T> 的枚举数:

public IEnumerator<GenericItem> GetEnumerator()
{
    return genericItemsList.GetEnumerator();
}

但是,在SpecificList 中,它似乎更棘手。将IEnumerator&lt;GenericItem&gt; 转换为IEnumerator&lt;SpecificItem&gt; 似乎有风险,我不知道这是否可行。相反,我做了以下事情:

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 Full Edition Pre-Release Build 5.1.1715.35。

另外,我应该停止运行 MSTest 单元测试:我只是按了 Ctrl+RCtrl+T 在 Chrome 中重新加载页面...

【问题讨论】:

    标签: c# iterator resharper ienumerable warnings


    【解决方案1】:

    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;
        }
    }
    

    我相当肯定这个错误已在 4.0 版的 C# 编译器中得到修复。

    【讨论】:

    • 谢谢。可能是一个愚蠢的问题,但我使用的 C# 编译器的版本是否取决于我使用的 .NET 版本?这是一个 .NET 3.5 项目——这能保证我使用特定版本的 C# 编译器吗?
    • @Sarah,它与您正在运行的 Visual Studio 版本比您所针对的框架更相关。 2008 = C# 3.0 和 2010 = C# 4.0
    • 啊哈!我在2008 SP1。您的建议删除了 ReSharper 警告,一切似乎都有效。 :)
    【解决方案2】:

    IEnumerator&lt;GenericItem&gt; 转换为IEnumerator&lt;SpecificItem&gt; 似乎有风险,我不知道这是否可行。

    肯定会的。

    return base.Cast<SpecificItem>().GetEnumerator();
    

    与您当前的实施相比,风险不会增加或减少。事实上,我很确定它或多或少是相同的代码。

    【讨论】:

    • 这让 Visual Studio 2008 很生气。 Cast 以红色突出显示,并显示“无法解析符号 'Cast'”。
    • @Sarah - 您可能需要添加 using System.Linq;
    • @ChaosPandion:已经有一个using 指令用于System.Linq
    猜你喜欢
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    相关资源
    最近更新 更多