泛型类型推理与活力的工作? [英] Generic type inference not working with dynamic?

查看:107
本文介绍了泛型类型推理与活力的工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在玩海量,一个Micro-ORM返回的IEnumerable<的集合;动态方式>

I have recently been playing with Massive, a Micro-ORM which returns collections of IEnumerable<dynamic>.

我发现了一个意想不到的问题,当我试图查询的一种使用LINQ的集合。

I discovered an unexpected issue when I tried to query one of those collections using LINQ.

虽然编译器似乎已经没有任何问题的工作指出,即使的String.Format返回一个字符串的时候传递给它的论据之一是声明为动态...

While the compiler seems to have no issues whatsoever to work out that string.Format returns a string even when one of the arguments passed to it is declared as dynamic...

dynamic dynamicString = "d"; // just using a string here for simplicity, same problem occurs with any other type
string explicitString = string.Format("string is {0}", dynamicString); // works without issues



...这似乎并不能够推断事实以下情形:

...it doesn't appear to be able to infer that fact in the following scenario:

IEnumerable<string> strings = new[] { "a", "b", "c" };
IEnumerable<dynamic> dynamics = strings;

IEnumerable<string> output = dynamics.Select(d => string.Format("string is {0}", d)); // compiler error on this line



编译器会抱怨:

The compiler complains:

"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<dynamic>' to 'System.Collections.Generic.IEnumerable<string>'. An explicit conversion exists (are you missing a cast?)"

由于编译器应该能够推断出我的lambda表达式返回一个字符串,我本来期望它也推断选择的TResult应该是字符串类型(而不是动态)。

Since the compiler should be able to infer that my lambda expression returns a string, I would have expected it to also infer that the TResult of the Select should be of type string (and not dynamic).

这是很容易通过指定修复在TSource和TResult明确如下:

It was easy to fix by specifying the TSource and TResult explicitly like this:

IEnumerable<string> output2 = dynamics.Select<dynamic, string>(d => string.Format("string is {0}", d)); // works !!!



或者,我可以把结果赋值给一个IEnumerable<动态> ...

Or I could assign the result to an IEnumerable<dynamic>...

IEnumerable<dynamic> output3 = dynamics.Select(d => string.Format("string is {0}", d)); // also works



我也证实,当我代替我的IEnumerable<不会出现此问题;动态> ;有一个IEnumerable<对象>

I have also confirmed that this problem does not occur when I replace my IEnumerable<dynamic> with an IEnumerable<object>:

IEnumerable<object> objects = strings;
IEnumerable<string> output4 = objects.Select(o => string.Format("string is {0}", o)); // works



有趣的是,即使以下工作:

And interestingly even the following works:

IEnumerable<string> output5 = dynamics.Select(d => string.Format("string is {0}", (object)d)); // works
IEnumerable<string> output6 = dynamics.Select(d => string.Format("string is {0}", (string)d)); // works



任何人能解释这是怎么回事呢? ?这是C#编译器的一个已知限制或有我发现了另一个错误

Can anybody explain what's going on here? Is this a know limitation of the C# compiler or have I found yet another bug?

推荐答案

您需要:

IEnumerable<string> output = dynamics.Select(d => (string)string.Format(
       "string is {0}", d));



它无法推断返回类型为字符串,因为动态意味着它必须承担回报动态,如果有更合适的超载的的String.Format 为提供(用不同的返回类型)的特定类型。即使我们知道,否则,该规范为动态会同意我们的观点,P通过增加一个显式类型转换回字符串 。我们做的返回类型明确

It can't infer the return type is string, because the dynamic means it has to assume the return is dynamic, in case there is a more suitable overload of string.Format for the specific type supplied (with a different return type). Even if we know otherwise, the spec for dynamic will disagree with us ;p By adding an explicit cast back to string we make the return type clear.

就个人而言,我看不出使用了动态在这里;你还不如用对象,那么它是不是摆在首位的问题:

Personally, I see no use for dynamic here; you might as well use object, then it isn't an issue in the first place:

IEnumerable<string> strings = new[] { "a", "b", "c" };
IEnumerable<object> dynamics = strings;

IEnumerable<string> output = dynamics.Select(d => string.Format(
      "string is {0}", d));



(或实际上,保留为的IEnumerable<串> )我假定你有一些其他原因使用动态,是不是在这个例子中可见。

(or indeed, leave as IEnumerable<string>) I assume you have some other reason to use dynamic that isn't visible in this example.

这篇关于泛型类型推理与活力的工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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