为什么我在此示例代码中没有出现语法错误?

时间:2016-07-29 22:28:14

标签: c# casting syntax-error igrouping

只是尝试使用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)}");

显然,我在无效演员表上遇到运行时错误。但我希望,这对编译器来说很有用......

1 个答案:

答案 0 :(得分: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撰写的一篇很好的博客post,其中介绍了如何在foreach中使用Duck打字:

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

提供一个不带参数的公共方法GetEnumerator并返回一个包含两个成员的类型:a)不带参数并返回布尔值的方法MoveMext,以及b)属性{{ 1}}使用一个返回Object的getter。