警告 - 未实现 'collection' 模式
Warning - does not implement the 'collection' pattern
我正在收集,明确实施 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
收到编译器警告:
Warning CS0279 'MyCollection' does not implement the 'collection' pattern. 'MyCollection.GetEnumerator()' is either static or not public.
天哪,这不是 public。为什么会这样?我 可以 使它成为 public,但对于 foreach
类型之外的类型不需要它:
foreach (var item in new MyCollection<string>()) { } // no warning
我是不是做错了什么?
在此处查看编译器警告 CS0279 的解释:https://msdn.microsoft.com/en-us/library/bz2286x8(v=vs.90).aspx
There are several statements in C# that rely on defined patterns, such
as foreach and using. For example, foreach relies on the collection
class implementing the enumerable pattern. This error occurs when the
compiler is unable to make the match due to a method being declared
static or not public. Methods in patterns are required to be instances
of classes, and to be public.
(强调我的)
存在警告是因为 C# 编译器可以用多种不同的方式处理 foreach
。其中一种方法是找到具有合适 return 类型的 GetEnumerator
方法。在 之前 编译器检查表达式的类型是否实现 IEnumerable
或 IEnumerable<T>
.
在你的例子中,它找到了单一的无参数 GetEnumerator
方法,但它不是 public。 C# 规范建议此时发出警告,因为您可能 打算 它可用于 foreach
。来自 C# 5 规范,第 8.8.4 节,强调我的:
- Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
以下任何一项都可以解决问题:
将 GetEnumerator
重命名为 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
中,但在 IEnumerable.GetEnumerator
中将 this
转换为 IEnumerable<T>
以调用它:
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<T>) this).GetEnumerator();
IEnumerator<T> IEnumerable<T>.GetEnumerator() => { yield return default(T); }
我正在收集,明确实施 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
收到编译器警告:
Warning CS0279 'MyCollection' does not implement the 'collection' pattern. 'MyCollection.GetEnumerator()' is either static or not public.
天哪,这不是 public。为什么会这样?我 可以 使它成为 public,但对于 foreach
类型之外的类型不需要它:
foreach (var item in new MyCollection<string>()) { } // no warning
我是不是做错了什么?
在此处查看编译器警告 CS0279 的解释:https://msdn.microsoft.com/en-us/library/bz2286x8(v=vs.90).aspx
There are several statements in C# that rely on defined patterns, such as foreach and using. For example, foreach relies on the collection class implementing the enumerable pattern. This error occurs when the compiler is unable to make the match due to a method being declared static or not public. Methods in patterns are required to be instances of classes, and to be public.
(强调我的)
存在警告是因为 C# 编译器可以用多种不同的方式处理 foreach
。其中一种方法是找到具有合适 return 类型的 GetEnumerator
方法。在 之前 编译器检查表达式的类型是否实现 IEnumerable
或 IEnumerable<T>
.
在你的例子中,它找到了单一的无参数 GetEnumerator
方法,但它不是 public。 C# 规范建议此时发出警告,因为您可能 打算 它可用于 foreach
。来自 C# 5 规范,第 8.8.4 节,强调我的:
- Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
以下任何一项都可以解决问题:
将
GetEnumerator
重命名为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
中,但在IEnumerable.GetEnumerator
中将this
转换为IEnumerable<T>
以调用它:IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<T>) this).GetEnumerator(); IEnumerator<T> IEnumerable<T>.GetEnumerator() => { yield return default(T); }