为什么不能通过扩展方法使用来推断类型?

时间:2016-04-05 12:11:02

标签: c# generics extension-methods

请参阅以下最近的答案:

https://stackoverflow.com/a/36421418/1017882

总结一下,编写了一个使用泛型的扩展方法:

static TResult GetEntry<TEnum, TResult>(this Dictionary<TEnum, string> dictionary, TEnum key) {...}

如果这样调用,一切正常:

var attributes = new Dictionary<MyTestEnum, string>();
var result = attributes.GetEntry<MyTestEnum, double>(MyTestEnum.First);

但如果我以不同方式调用它:

var result = attributes.GetEntry(MyTestEnum.First);

显然,编译器无法再推断出类型。但是很明显(基于 attributes是什么),我试图通过什么类型。

为什么我要明确我传递的是什么类型?这感觉就像不必要的代码。

通常这样的问题可以通过示例用法来回答,如果没有这种额外信息就会“破解” - 但我想不出这样的任何情况。

更多上下文

我甚至尝试放弃那一点语法的原因是因为我(模糊地)回想起能够通过某些通用用途这样做。我想看看它如何适用于这样的集合。

1 个答案:

答案 0 :(得分:5)

  

但是很清楚地看到(基于什么属性),我试图通过什么类型。

但不是你试图通过它。

TResult不依赖于传递的任何类型,因此无法知道您想要GetEntry<MyTestEnum, double>而不是GetEntry<MyTestEnum, int>GetEntry<MyTestEnum, MyTestEnum>或您有什么。< / p>

有些人使用比编译器使用的更广泛的上下文可以看到即使编译器无法推断它的含义,但这不是其中之一。我只能猜测你可能想要GetEntry<MyTestEnum, double>,因为这是你在问题中早先使用的例子。

如果另一方面你有类似的东西:

public static TResult GetEntry<TKey, TResult>(Dictionary<TKey, TResult> dict, TKey key)
{
  return dict[key];
}

然后因为所有的类型参数都与它所调用的部分签名相关,所以它确实是可推断的,尽管仍有更微妙的情况,这种推断不会发生。