IEnumerable与的C#变体问题
参见英文答案 >
Method overload resolution with regards to generics and IEnumerable????????????????????????????????????2个
所以,我遇到类似代码的问题如下: public static String MyFunc<T>(this IEnumerable<T> list) where T : struct { ... some code ... return myString; } public static String MyFunc<T>(this T o) where T : struct { ... some code ... return myString; } 问题是当尝试在List上调用MyFunc时,它使用第二个函数而不是接受IEnumerable的函数.我知道这与方差有关,但我不确定如何强制它使用第一个函数而不是第二个函数.我用来调用第一个代码的代码是: List<int> x = new List<int>(); String s = x.MyFunc(); 上面的代码立即转到第二个函数,我需要它来使用第一个.我该如何强迫所需的行为?顺便说一下,我使用的是.NET 4.0 解决方法
它当前选择第二种方法的原因是从类型到自身的转换(第二种方法,T = List< int>,从List< int>到List< int>的转换)总是比转换“更好”到它实现的类型(第一种方法,T = int,从List< int>到IEnumerable< int>的转换).顺便说一句,这与方差无关 – 它只是方法重载算法和类型推断.
请注意,使用当前代码,虽然选择了第二个重载,但随后会发现它无效,因为T违反了T:struct约束.仅在选择过载后才检查约束.有关详细信息,请参见Eric Lippert’s blog post on this. 我建议你只给两种方法不同的名字. 编辑:正如安东尼在评论中指出的那样,如果你把它称为: x.AsEnumerable().MyFunc(); 或者只是将声明更改为: IEnumerable<int> x = new List<int>(); x.MyFunc(); 我并不完全清楚为什么它在这里更好 – 在这种情况下,在类型参数替换之后,你基本上得到了IEnumerable< T>作为两种情况下的参数类型.但是,我仍然强烈建议在这里使用不同的名称.事实上,让我对规范感到困惑,以确定调用哪个重载应该足以表明每个阅读代码的人都不会立即清楚这种行为. 编辑:我认为原因在于(来自C#5规范,第7.5.3.2节):
因此,即使后者涉及类型参数,T的特定性也不如IEnumerable< T>.我仍然不清楚这是否是语言设计者的预期行为…我可以看到为什么涉及类型参数的类型应该被视为不比不涉及类型参数的类型更具体,但不是这个措辞… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |