代码之家  ›  专栏  ›  技术社区  ›  Sinatr

警告-未实现“收集”模式

  •  -1
  • Sinatr  · 技术社区  · 7 年前

    IEnumerable

    public class MyCollection<T> : IEnumerable<T>, IEnumerable
    {
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
        IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
        IEnumerator<T> GetEnumerator() { yield return default(T); } // test
    
        public void Test()
        {
            foreach (var item in this) { } // here is warning
        }
    }
    

    我在收到编译器警告 this :

    是的,这不是公开的。为什么会这样?我 可以 公开,但不需要 foreach

    foreach (var item in new MyCollection<string>()) { } // no warning
    

    2 回复  |  直到 7 年前
        1
  •  4
  •   Jon Skeet    7 年前

    警告的存在是因为C编译器可以处理 foreach 以多种不同的方式。其中一种方法是找到 GetEnumerator 之前 编译器检查表达式的类型是否实现 IEnumerable IEnumerable<T>

    方法,但它不是公共的。C#规范建议在这一点上发出警告,您可能已经知道了 foreach公司 . 根据C#5规范第8.8.4节,强调:

    • 如果重载解析产生除明确的公共实例方法或没有适用方法之外的任何结果,建议发出警告。

    以下任何一项都可以解决问题:

    • 重命名 GetEnumeratorImpl

      IEnumerator IEnumerable.GetEnumerator() => GetEnumeratorImpl();
      IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumeratorImpl();
      IEnumerator<T> GetEnumeratorImpl() { yield return default(T); }
      
    • 不要使用显式接口实现 IEnumerable<T>.GetEnumerator() -将实现放在那里

      IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
      public IEnumerator<T> GetEnumerator() => { yield return default(T); }
      
    • 实施 IEnumerable<T>.GetEnumerator this IEnumerable<T> IEnumerable.GetEnumerator 称之为:

      IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<T>) this).GetEnumerator();
      IEnumerator<T> IEnumerable<T>.GetEnumerator() => { yield return default(T); }
      
        2
  •  2
  •   Owen Pauling    7 年前

    https://msdn.microsoft.com/en-us/library/bz2286x8(v=vs.90).aspx

    C语言中有几个语句依赖于定义的模式,例如 作为foreach . 当 由于声明了一个方法,编译器无法进行匹配 模式中的方法必须是实例 并公开

    (强调矿山)