【问题标题】:How to handle a dynamic class differently based on expected return value如何根据预期返回值以不同方式处理动态类
【发布时间】:2013-01-04 10:46:51
【问题描述】:

我必须重写DynamicObject 的哪个方法才能根据使用实例的上下文获得不同的行为(在动态类中)?

这是我想要完成的一个示例:

class DynamicTest : DynamicObject
{
    public DynamicTest(string xyz)
    {
        _xyz = xyz;
    }

    private string _xyz;

    //TODO: what do I need to implement to get required behaviour?
}

class Program
{
    static void Main(string[] args)
    {
        dynamic foo = new DynamicTest("test);

        if (foo)  // treat foo as boolean
        { // jump in here when _xyz of foo has a value
            System.Console.WriteLine(foo); //treat foo as string
        }
        else
        { // jump in here when _xyz of foo is null
            System.Console.WriteLine("No Value In Object");
        }
    }
}

【问题讨论】:

  • 请问您为什么要这样做?为什么不想访问某个谓词中的字段?
  • 在python中,一个有值的字段被认为是真,没有值是假的。我想要类似的行为。

标签: c# .net dynamic dynamicobject


【解决方案1】:

我不知道你为什么要这样做,我肯定会推荐这样做,但你可以覆盖 DynamicObject 上的 TryConvert 方法,例如:

class DynamicTest : DynamicObject
{
    public DynamicTest(string xyz)
    {
        _xyz = xyz;
    }
    private string _xyz;


    public override bool TryConvert(ConvertBinder binder, out Object result)
    {
        Console.WriteLine ("TryConvert was called");
        Console.WriteLine ("Is explicit: "+binder.Explicit);
        if(binder.Type == typeof(bool))
        {
            result = true;
            return true;
        }
        else if(binder.Type == typeof(string))
        {   
            result = _xyz;
            return true;
        }

        result = null;
        return false;
    }

    public override string ToString()
    {
        return _xyz;
    }
}

现在有一些问题:Console.WriteLine 需要ToString,如果不存在隐式转换,它不会尝试转换(因为WriteLine 已重载),所以它调用ToString。到 bool 的隐式和显式转换通过,但如果你在 if - 中使用 foo - 你会得到 RuntimeBinderException: Cannot implicitly convert type 'DynamicTest' to 'bool'

示例:

dynamic foo = new DynamicTest("test:");
bool boolFoo = foo; //passes, TryConvert is called with `binder.Explicit` == false
bool boolFoo1 = (bool)foo; //passes, TryConvert is called with `binder.Explicit` == true
if(foo) //throws RuntimeBinderException

【讨论】:

  • 我想要这种行为,因为在许多动态语言中,有值的对象被认为是真,没有值是假的。在没有动态关键字的 c# 中,您需要显式比较。什么是好的,但不是在我正在处理的 api 中。
【解决方案2】:

我觉得implicit operator可以帮到你

示例代码:

class DynamicTest : DynamicObject
{
    public DynamicTest(string xyz)
    {
        _xyz = xyz;
    }

    private string _xyz;

    public static implicit operator bool(DynamicTest rhs)
    {
        return rhs._xyz != null;
    }

    public static implicit operator string(DynamicTest rhs)
    {
        return rhs._xyz;

    }

    //TODO: what to override to get required behaviour
}



class Program
{
    static void Main(string[] args)
    {
        dynamic foo = new DynamicTest("test");


        if (foo)  // treat foo as boolean
        { // jump in here when _xyz of foo has a value
            System.Console.WriteLine((string)foo); //treat foo as string   //Importat: (string)foo to go operatorstring 
        }
        else
        { // jump in here when _xyz of foo is null
            System.Console.WriteLine("No Value In Object");
        }


    }
}

【讨论】:

    猜你喜欢
    • 2015-07-04
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多