-1

只是用 C# Lookup 集合尝试了一些基础知识,发现这个简单的示例编译得很好,即使是IGrouping接口也应该将TElement设置为 int。

string txt = "Hello world!";
ILookup<char, int> occurrences = Enumerable.Range(0, txt.Length).ToLookup(i => txt[i], i => i);

foreach (IGrouping<char, string> values in occurrences)
    Console.WriteLine($"{values.Key}: {string.Join(", ", values)}");

显然,我在无效转换时遇到运行时错误。但我预计,这适用于编译器......

4

1 回答 1

1

这似乎是编译器使用的规则:

如果编译器可以看到值类型或密封类没有实现或继承程序员尝试转换的类型,则转换在编译时是非法的。

(感谢 Jeppe Stig Nielsen 在评论中提到这一点。)

foreach (XXXX values in occurrences)如果您使用以下任一选项而不是XXXX您的示例,这是编译的结果。注意是派生自occurrences的类型。ILookup<char, int>IGrouping<char, int>

  • public class MyClass { }编译
  • public sealed class MyClass { }编译时错误
  • public sealed class MyClass : IGrouping<char, int> {...}编译
  • public sealed class MyClass : IGrouping<char, string> {...}编译时错误
  • public struct MyStruct {}编译时错误
  • public struct MyStruct : IGrouping<char, string> {...} 编译时错误
  • public struct MyStruct : IGrouping<char, int> {...}编译

这是 Krzysztof Cwalina 的一篇很好的博客文章,描述了 Duck 如何在 foreach 中使用输入:

C# 的 foreach 运算符已经使用了鸭子类型。这可能会让一些人感到惊讶,但要在 C# 中支持 foreach,您不需要实现IEnumerable!你所要做的就是:

提供一个GetEnumerator不带参数并返回具有两个成员的类型的公共方法:a)MoveMext不带参数并返回布尔值的方法,以及 b) 具有Current返回 Object 的 getter 的属性。

于 2016-07-29T22:54:59.280 回答