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

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

问题描述

我想写一个扩展法,将字典上的值分别为某种序列的工作。不幸的是,编译器似乎无法推断从我的方法的使用的通用参数;我需要明确指定它们

 公共静态无效的someMethod< TKEY的,TUnderlyingValue,TValue> 
(这IDictionary的< TKEY的,TValue>字典)
式TValue:IEnumerable的< TUnderlyingValue> {}

静态无效使用()
{
变种字典=新词典< INT,字符串[]>();
变种dict2 =新词典< INT,IEnumerable的<串GT;>();

//这些不进行编译
dict.SomeMethod();
的someMethod(字典); //没有任何与扩展的方法
dict2.SomeMethod(); //希望这会更容易推断出,但没有喜悦


//这些做工精细
dict.SomeMethod< INT,字符串,字符串[]>();
dict2.SomeMethod< INT,字符串的IEnumerable<串GT;>();
}



我认识到,类型推断是不是一门精确的科学,但我想知道如果有一些基本的规则,我在这里失踪 - 我不熟悉规范的细节




  1. 这是一个推理过程或缺点是我的期望在这种情况下,该编译器应该弄明白不合理(歧义也许)?

  2. 我可以的方式,将使它同样功能但inferrable?


解决方案

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




我不知道我同意。该规范是相当细致。




我不知道是否有一些基本的规则,我在这里失踪。




你缺少的基本规则是可能是制约不是签名的一部分。类型推断工作过的签名。



有在我看来,良好的原因是设计决策。然而,许多人认为我是不道德的行为相信有充分的理由为设计决策。如果你有兴趣读什么感觉对我是否正确或错误的话题几百万字,看到关于这个问题我的文章和百元左右的评论告诉我,我是错的:



http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx




这是推理过程的一个缺点?




可以说,是。在我看来,这是鉴于竞争的设计要求合理的选择。 (是的那些做用户意味着什么和给出错误时,事情看起来暧昧。)




我的期望是编译器应该看着办吧,在这种情况下,不合理的?




没有。你看起来像一个通情达理的人,和你的期望似乎是建立在良好的推理。然而,这是完全可能有一个合理的预期,仍然是未得到满足。这将是这些案件之一。




我可以更改方法的的方式,将使它同样功能但inferrable签名?




这将是困难的,因为一般的词典类型不在其转换协变或逆变。你想要捕捉的概念没有在类型系统在得到推论的方式简单地表示。



如果您更喜欢使用的语言更先进的类型推断,可以考虑使用F#。如果您希望对歪斜语言做用户的意思,而不是,可以考虑使用VB上模棱两可报告的错误。


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. Is this a shortcoming of the inference process or is my expectation that the compiler should "figure it out" unreasonable in this case (ambiguity perhaps)?
  2. Can I change the method's signature in a way that would make it equally functional yet 'inferrable'?

解决方案

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:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

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'?

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.

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天全站免登陆