为什么不能从扩展方法的使用中推断类型?

3

请看以下最近的回答:

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);

显然编译器不能再推断类型了。但是根据属性的内容很清楚,我试图传递的是什么类型。

为什么我必须明确传递的类型?这似乎是不必要的代码。

通常此类问题的答案会举出没有这种额外信息会导致错误的示例用法 - 但是我想不到任何这样的情况。

更多上下文

我之所以尝试在第一次中使用这个语法,是因为我(模糊地)记得可以在某些泛型使用中这样做。我想知道它如何应用于这样的集合。


6
编译器如何推断 TResult?我认为返回类型不会参与泛型推断,所以 string result = attributes.GetEntry(MyTestEnum.First) 也行不通。 - Lee
@Lee - 当然!我没有足够的注意力。我以为TResult是作为扩展参数的一部分传递的。 - user1017882
1个回答

5

但很清楚(基于哪些属性),我试图传递的是什么类型,但不知道您尝试以何种方式传递它。

TResult 不依赖于任何传递的类型,因此无法确定您想要 GetEntry<MyTestEnum, double> 而不是 GetEntry<MyTestEnum, int>GetEntry<MyTestEnum, MyTestEnum> 等等。

有时,人类可以使用比编译器更广泛的上下文来看到意思,即使编译器无法推断出来,但这不是这种情况。我只能猜测您可能想要 GetEntry<MyTestEnum, double>,因为这是您在问题中早期使用的示例。

如果您有像下面这样的内容:

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

由于所有类型参数都与其被调用的部分签名有关,因此确实可以进行推断,尽管仍存在一些更微妙的情况,无法发生这样的推断。


根据我对李的评论,我错过了这个 :( 很好的发现。+1。谢谢回复。 - user1017882

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接