简体   繁体   English

为什么dynamic.ToString()在字符串而不是字符串之间返回一些东西?

[英]Why does dynamic.ToString() return something between a string and not a string?

I use a type derived from a DynamicObject as a builder for some strings. 我使用从DynamicObject派生的类型作为某些字符串的构建器。 At the end I call ToString to get the final result. 最后,我调用ToString来获得最终结果。

At this point I thought it would give me a normal string but this string is somehow strange. 在这一点上,我认为它会给我一个正常的字符串,但这个字符串有点奇怪。 It behaves like one when I use string functions on it but it behaves like I don't know actually what, something neither a string nor a dynamic. 当我在其上使用字符串函数时,它的行为就像一个,但它的行为就像我实际上不知道什么,既不是字符串也不是动态。


This is how I implemented ToString on my builder 这就是我在构建器上实现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();
    }
}

When I run it like this 当我像这样运行它

dynamic example = new Example();
Console.WriteLine(example.ToString().ToUpper());

the result is correct: USERQUERY+EXAMPLE (when executed in LINQPad) 结果是正确的: USERQUERY+EXAMPLE (在LINQPad中执行时)

However if I call the second line like this 但是,如果我像这样打电话给第二行

Console.WriteLine(example.ToString().Extension());

where 哪里

static class Extensions
{
    public static string Extension(this string str)
    {
        return str.ToUpper();
    }
}

the application crashes with a RuntimeBinderException saying 应用程序崩溃与RuntimeBinderException

'string' does not contain a definition for 'Extension' 'string'不包含'Extension'的定义

but if I cast the result it works again 但如果我把结果再次投入使用

Console.WriteLine(((string)example.ToString()).Extension());

Maybe one more example. 也许还有一个例子。

Console.WriteLine((string)example); // UserQuery+Example

but

Console.WriteLine(example); // DynamicObject UserQuery+Example 

You can actually never be sure what you'll get until you cast it to string. 实际上,在将其转换为字符串之前,您永远无法确定您将获得什么。


Why is this happening and is there a way to avoid the additional cast and get somehow a real string? 为什么会发生这种情况,有没有办法避免额外的演员表,并以某种方式获得真正的字符串?

That's because ToString called on dynamic is typed to return dynamic and not string : 那是因为调用dynamicToString是为了返回dynamic而不是string

dynamic example = new Example();
// test will be typed as dynamic
var test = example.ToString();

When you call ToUpper on test it will use dynamic binding and resolve to string.ToUpper at runtime. 当您在test时调用ToUpper时,它将使用动态绑定并在运行时解析为string.ToUpper You have to cast to a concrete type to escape dynamic typing. 您必须转换为具体类型以逃避动态类型。

Extension methods is a compile-time feature and as such is not supported by dynamic typing as extension method . 扩展方法是编译时功能,因此dynamic类型不支持扩展方法 You can still call it using regular static method invocation syntax. 您仍然可以使用常规静态方法调用语法来调用它。

Extensions.Extension(example.ToString());

But again - example.ToString() will return dynamic and type binding will happen at runtime to check if it can be used as a parameter to Extensions.Extension call. 但是再次 - example.ToString()将返回dynamic并且类型绑定将在运行时发生,以检查它是否可以用作Extensions.Extension调用的参数。 Check this answer for details. 请查看此答案以获取详细信

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM