为什么dynamic.ToString()在字符串而不是字符串之间返回一些东西?
我使用从DynamicObject
派生的类型作为某些字符串的构建器。 最后,我调用ToString
来获得最终结果。
在这一点上,我认为它会给我一个正常的字符串,但这个字符串有点奇怪。 当我在其上使用字符串函数时,它的行为就像一个,但它的行为就像我实际上不知道什么,既不是字符串也不是动态。
这就是我在构建器上实现ToString
public class Example : DynamicObject { public override bool TryConvert(ConvertBinder binder, out object result) { if (binder.ReturnType == typeof(string)) { result = ToString(); return true; } result = null; return false; } public override string ToString() { return base.ToString(); } }
当我像这样运行它
dynamic example = new Example(); Console.WriteLine(example.ToString().ToUpper());
结果是正确的: USERQUERY+EXAMPLE
(在LINQPad中执行时)
但是,如果我像这样打电话给第二行
Console.WriteLine(example.ToString().Extension());
哪里
static class Extensions { public static string Extension(this string str) { return str.ToUpper(); } }
应用程序崩溃与RuntimeBinderException
说
‘string’不包含’Extension’的定义
但是如果我投出结果它再次起作用
Console.WriteLine(((string)example.ToString()).Extension());
也许还有一个例子。
Console.WriteLine((string)example); // UserQuery+Example
但
Console.WriteLine(example); // DynamicObject UserQuery+Example
实际上,在将它转换为字符串之前,你永远不能确定你会得到什么。
为什么会发生这种情况,有没有办法避免额外的演员表,并以某种方式得到一个真正的字符串?
这是因为调用dynamic
的ToString
是为了返回dynamic
而不是string
:
dynamic example = new Example(); // test will be typed as dynamic var test = example.ToString();
当您在test
时调用ToUpper
时,它将使用动态绑定并在运行时解析为string.ToUpper
。 您必须转换为具体类型以逃避动态类型。
扩展方法是编译时function,因此dynamic
类型不支持扩展方法 。 您仍然可以使用常规静态方法调用语法来调用它。
Extensions.Extension(example.ToString());
但是再次 – example.ToString()
将返回dynamic
并且类型绑定将在运行时发生,以检查它是否可以用作Extensions.Extension
调用的参数。 请查看此答案以获取详细信