【发布时间】:2011-04-27 11:57:41
【问题描述】:
我想编写一个扩展方法,该方法适用于其值是某种序列的字典。不幸的是,编译器似乎无法从我对该方法的使用中推断出通用参数。我需要明确指定它们。
public static void SomeMethod<TKey, TUnderlyingValue, TValue>
(this IDictionary<TKey, TValue> dict)
where TValue : IEnumerable<TUnderlyingValue> { }
static void Usage()
{
var dict = new Dictionary<int, string[]>();
var dict2 = new Dictionary<int, IEnumerable<string>>();
//These don't compile
dict.SomeMethod();
SomeMethod(dict); // doesn't have anything to do with extension-methods
dict2.SomeMethod(); // hoped this would be easier to infer but no joy
//These work fine
dict.SomeMethod<int, string, string[]>();
dict2.SomeMethod<int, string, IEnumerable<string>>();
}
我意识到类型推断不是一门精确的科学,但我想知道这里是否缺少一些基本的“规则”——我不熟悉规范的细节。
- 这是推理过程的一个缺点,还是我期望编译器在这种情况下“弄清楚”是不合理的(可能是模棱两可)?
- 我能否更改方法的签名,使其具有同等功能但“可推断”?
【问题讨论】:
-
推断 TUnderlyingValue 可能很困难。特别是因为
IEnumerable<>的类型参数在.net 4 中是协变的。 -
类型推断是一门具有形式算法的精确科学,它不仅仅是一种猜测。如果编译器无法推断出类型,那只是因为它没有特定的规则来处理某些情况,而且通常是实现设计,而不是限制。看这里:classes.cs.uchicago.edu/archive/2005/winter/33600-1/slides/…
-
@Jack:谢谢你的链接;那很有意思。请参阅我对 Eric Lippert 的回答的评论,了解我的意思。我想我用词不当。
标签: c# generics type-inference