【问题标题】:dynamic.ToString() unexpected behaviourdynamic.ToString() 意外行为
【发布时间】:2019-12-07 18:15:04
【问题描述】:

我想知道这段代码是如何工作的:

dynamic dynaString = 2;
string b = dynaString.ToString();

当这个不工作时:

var list = new List<dynamic>();
var liststring = new List<string>();
liststring = list.Select(x => x.ToString()).ToList();

我知道我可以在 Select 语句之后添加 Cast&lt;string&gt; 但这并不能解释这种行为。为什么在代码中声明的动态变量上调用动态元素上的ToString() 与在从 LINQ 中的列表中获取的动态变量上调用时不同。

我查看了Select 的方法签名,它是:

我的猜测是 x 这里是一个动态变量,所以它的行为应该和 dynaString 一样,但事实并非如此。 Intellisense 建议我这个x.ToString() 返回string

谁有 C# 动力学方面的经验,可以解释一下吗?


我也试过这个代码:

var list = new List<dynamic>();
var liststring = new List<string>();
foreach (dynamic a in list)
{
    liststring.Add(a.ToString());
}

它按预期编译,因为 a 在 foreach 语句中再次声明为动态。

【问题讨论】:

  • @SᴇM 按照您的建议,我找到了这个答案stackoverflow.com/a/4893408/1714342,但它仍然不能完全回答我的问题。 “只要你有一个“动态”的类型参数,编译器就会简单地生成“对象”作为类型参数。“动态”是 C# 语言的特性”这里不是这种情况。您可以将此处的所有动态更改为对象,它会编译,而动态则不会:)
  • 我不确定它是否能回答您的问题,但 aDynamic.ToString() 的返回类型是动态的,因此推断出 Select&lt;dynamic, dynamic&gt; .. 你不会期望它可以分配List&lt;dynamic&gt;List&lt;string&gt;。如果您改为指定Select&lt;dynamic, string&gt;,那应该可以。
  • @steve16351 好笑...它带来了更多问题:) 为什么编译器不选择&lt;dynamic,string&gt; 而不是&lt;dynami,dynamic&gt;?我试过liststring = list.Select&lt;dynamic,string&gt;(x =&gt; x.ToString()).ToList();,它按照你说的编译:)
  • 是的,它可以,但我相信这将基于返回类型推断,isn't possible

标签: c# .net string dynamic tostring


【解决方案1】:

根据dynamic type docs

动态类型表示使用变量和对其成员的引用绕过编译时类型检查。相反,这些操作是在运行时解决的。

在大多数情况下,动态类型的行为类似于类型对象。特别是,任何非空表达式都可以转换为动态类型。动态类型与对象的不同之处在于,包含动态类型表达式的操作不会被编译器解析或类型检查。

如果在编译时绕过类型检查和/或解析,则无法从使用中推断类型。

如果您省略泛型类型参数,即使您调用ToString() 方法,默认情况下也会返回dynamic 类型。原因是任何非空表达式都可以分配给dynamic。因为dynamic是源,所以也是Select(x =&gt; x.ToString())方法调用的结果。

另一方面,您可以在调用ToString() 时将dynamic 对象分配给string 变量,该变量返回string 实例。

【讨论】:

    猜你喜欢
    • 2017-03-10
    • 2019-05-01
    • 2011-07-15
    • 2011-04-27
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多