【问题标题】:Why does dynamic.ToString() return something between a string and not a string?为什么 dynamic.ToString() 返回字符串而不是字符串之间的东西?
【发布时间】:2017-01-01 12:30:05
【问题描述】:

我使用从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 而崩溃

“字符串”不包含“扩展”的定义

但如果我转换结果,它会再次起作用

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

也许还有一个例子。

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

但是

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

在将其转换为字符串之前,您实际上永远无法确定会得到什么。


为什么会发生这种情况,有没有办法避免额外的演员表并以某种方式获得 real 字符串?

【问题讨论】:

    标签: c# dynamic tostring


    【解决方案1】:

    这是因为在 dynamic 上调用的 ToString 被键入以返回 dynamic 而不是 string

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

    当您在test 上调用ToUpper 时,它将使用动态绑定并在运行时解析为string.ToUpper。您必须转换为具体类型才能 escape 动态类型。

    扩展方法是一个编译时特性,因此dynamic 键入作为扩展方法不支持。您仍然可以使用常规的静态方法调用语法来调用它。

    Extensions.Extension(example.ToString());
    

    但同样 - example.ToString() 将返回 dynamic 并且类型绑定将在运行时发生,以检查它是否可以用作 Extensions.Extension 调用的参数。详情请查看this answer

    【讨论】:

    • 好的,我明白为什么扩展不能直接在动态对象上工作,但这也不能工作 example.ToString().ToLower().Extension() 所以这意味着只要我不将它转换为具体类型,我'无论方法是否重新调整 intstring 或其他任何东西,都将始终返回 dynamic
    • 是的,你是对的。您需要强制转换为某些特定类型以逃避动态类型。该转换可以是显式的(通过使用(string)),也可以是通过将动态类型表达式分配给静态类型变量或将其作为参数传递给静态类型方法的隐式类型。
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多