泛型:在这种情况下,为什么编译器不能推断类型参数? [英] Generics: Why can't the compiler infer the type arguments in this case?

查看:31
本文介绍了泛型:在这种情况下,为什么编译器不能推断类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个扩展方法,它可以处理值是某种序列的字典.不幸的是,编译器似乎无法从我对该方法的使用中推断出通用参数;我需要明确指定它们.

I wanted to write an extension-method that would work on dictionaries whose values were some sort of sequence. Unfortunately, the compiler can't seem to infer the generic arguments from my usage of the method; I need to specify them explicitly.

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

我意识到类型推断不是一门精确的科学,但我想知道这里是否缺少一些基本的规则"——我不熟悉规范的细节.

I realize that type inference isn't an exact science, but I was wondering if there's some fundamental 'rule' I'm missing here - I'm not familiar with the details of the spec.

  1. 这是推理过程的缺点还是我的期望编译器应该在这种情况下弄清楚"不合理(可能含糊不清)?
  2. 我是否可以更改方法的签名,使其功能相同但可推断"?

推荐答案

更新:这个答案是十多年前写的;从那时起,类型推断规范和实现已经更新了几次,包括在推断期间如何使用约束的更改.这个答案应该只考虑历史意义;查阅 C# 规范的最新副本,了解类型推断在当前实现中的工作原理.

UPDATE: This answer was written over ten years ago; since then the type inference specification and implementation have been updated several times including changes to how constraints are used during inference. This answer should be considered of historical interest only; consult a recent copy of the C# specification to see how type inference works in current implementations.

我意识到类型推断不是一门精确的科学

I realize that type inference isn't an exact science

我不确定我是否同意.规范非常详细.

I'm not sure I agree. The spec is quite detailed.

我想知道这里是否缺少一些基本的规则"

I was wondering if there's some fundamental 'rule' I'm missing here

您遗漏的基本规则可能是约束不是签名的一部分.类型推断不依赖于签名.

The fundamental rule that you're missing is probably that constraints are not part of the signature. Type inference works off of the signature.

在我看来,做出这样的设计决定是有充分理由的.然而,许多人认为我认为该设计决策有充分的理由在道德上是错误的.如果您有兴趣阅读关于我是对还是错的主题的几百万字,请参阅我关于该主题的文章以及告诉我我错了的数百条评论:

There are in my opinion good reasons for that design decision. However, many people believe that I am morally wrong for believing that there are good reasons for that design decision. If you're interested in reading what feels like several million words on the topic of whether I'm right or wrong, see my article on the subject and the hundred or so comments telling me I'm wrong:

https://docs.microsoft.com/en-us/archive/blogs/ericlippert/constraints-are-not-part-of-the-signature

这是推理过程的缺点吗?

Is this a shortcoming of the inference process?

可以说,是的.在我看来,考虑到相互竞争的设计要求,这是一个合理的选择.(那些是按照用户的意思去做"和当事情看起来不明确时给出错误".)

Arguably, yes. In my opinion, it is a reasonable choice given competing design requirements. (Those being "do what the user meant" and "give errors when things look ambiguous".)

是我期望编译器应该弄清楚";在这种情况下不合理?

is my expectation that the compiler should "figure it out" unreasonable in this case?

没有.你看起来是一个通情达理的人,你的期望似乎是基于良好的推理.然而,完全有可能有一个合理的期望但没有得到满足.这就是其中一种情况.

No. You seem like a reasonable person, and your expectation appears to be based on good reasoning. However, it is entirely possible to have a reasonable expectation that nevertheless is unmet. This would be one of those cases.

我是否可以更改方法的签名,使其功能相同但可推断"?

Can I change the method's signature in a way that would make it equally functional yet 'inferrable'?

这会很困难,因为泛型 Dictionary 类型在其转换中不是协变或逆变的.您想要捕获的概念在类型系统中不容易以提供推理的方式表达.

That's going to be difficult, since the generic Dictionary type is not covariant or contravariant in its conversions. The concept you want to capture is not easily expressed in the type system in a manner that affords inference.

如果您更喜欢使用具有更高级类型推断的语言,请考虑使用 F#.如果您更喜欢倾向于按照用户的意思做"的语言与其在歧义上报告错误",不如考虑使用 VB.

If you prefer using languages with more advanced type inference, consider using F#. If you prefer languages that skew towards "do what the user meant" rather than "report errors on ambiguity", consider using VB.

这篇关于泛型:在这种情况下,为什么编译器不能推断类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆