为什么dynamic . tostring () (string. format (), Convert.ToStrin

本文关键字:Convert ToStrin format string dynamic 为什么 tostring | 更新日期: 2023-09-27 18:02:59

此问题仅供教育用途。我有这段代码,在编译时失败的行,我想写行文件。(File.WriteAllLines(@"C:'temp'processed.txt",contents);)

错误消息:

参数2:不能从'System.Collections.Generic.List<dynamic>'来'string[]' C:'hg'PricingEngine'Source'App'Support'PricingEngine. migrator 'Program.cs 49 57 PricingEngine。移居者

错误6最佳重载方法匹配"System.IO.File。WriteAllLines(string, string[])'有一些无效C:'hg'PricingEngine'Source'App'Support'PricingEngine. migrator 'Program.cs 49移居者

如果我注释掉最后一行并使用断点检查,所有行都是字符串,一切都很好。

代码:

public static void Main()
{
    var t = new List<dynamic>
    {
        new {name = "Mexico", count = 19659},
        new {name = "Canada", count = 13855},
    };
   var stringed =  t.Select(o => string.Format("{0} {1}", o.name, o.count)).Select(o => Convert.ToString(o)).ToList();
   File.WriteAllLines(@"C:'temp'processed.txt", stringed);
 }

为什么动态ToString(), string.Format()和Convert.ToString()是动态的?我是不是漏掉了什么明显的东西?

为什么dynamic . tostring () (string. format (), Convert.ToStrin

我觉得你的问题可以归结为:

dynamic d = "x";
var v = Convert.ToString(d);

v的编译时类型是dynamic,如在Visual Studio中将其悬停所示,您可能期望它是string。不需要列表或文件。

为什么呢?基本上,c#有一个简单的规则:几乎任何使用动态值的操作都有dynamic的结果。这意味着在执行时是否有编译时不知道的额外重载并不重要,例如

我所知道的唯一涉及动态值的操作结果不是动态的操作是:

  • is操作符,例如var b = d is Foo; // Type of b is bool
  • 转换,例如var x = (string) d; // Type of x is string
  • as操作符,例如var y = d as string; // Type of y is string
  • 构造函数调用,例如var z = new Bar(d); // Type of z is Bar

对于方法调用的简单情况,c# 5规范的7.6.5节明确指出Convert.ToString(d)将具有dynamic类型:

调用表达式是动态绑定的(§7.2.2),如果至少满足以下条件之一:

    主表达式的编译时类型是动态的。
  • 可选参数列表中至少有一个参数具有编译时类型dynamic,且主表达式没有委托类型。

在这种情况下,编译器将调用表达式分类为dynamic类型的值。

(作为旁注,"and 主表达式没有委托类型"部分似乎没有在任何地方得到解决,也没有被编译器所尊重。如果您有Func<string, string> func = ...; var result = func(d);,则result的类型仍然显示为dynamic而不是string。)

由于动态的工作方式,编译器不知道t.name的类型,因此无法为File.WriteAllLines方法找到正确的重载。一种解决方案可能是显式地将t.name转换为string,但在您的情况下,您可以对数组使用隐式类型,并完全停止使用dynamic:

var t = new[]
{
    new {name = "Mexico", count = 19659},
    new {name = "Canada", count = 13855},
    new {name = "U.K.", count = 3286},
    new {name = "France", count = 2231},
    new {name = "Italy", count = 2201},
    new {name = "Germany", count = 1688},
    new {name = "Jamaica ", count = 1688},
    new {name = "Bahamas ", count = 1538},
    new {name = "Japan", count = 1538},
    new {name = "People's Republic of China", count = 1327},
    new {name = "Spain", count = 995},
    new {name = "Netherlands", count = 904},
    new {name = "Hong Kong", count = 904},
    new {name = "India", count = 904},
    new {name = "Ireland", count = 844},
    new {name = "Republic of China (Taiwan)", count = 693},
    new {name = "Switzerland ", count = 633},
    new {name = "Republic of Korea", count = 633},
    new {name = "Australia", count = 603},
    new {name = "Greece", count = 482},
};