【问题标题】:.net DynamicObject implementation that returns null for missing properties rather than a RunTimeBinderException.net DynamicObject 实现,为缺少的属性返回 null 而不是 RunTimeBinderException
【发布时间】:2011-06-09 19:29:10
【问题描述】:

我希望能够执行以下操作:

dynamic a = new ExpandoObject();
Console.WriteLine(a.SomeProperty ?? "No such member");

但这会引发

RunTimeBinderException: 'System.Dynamic.ExpandoObject' does not contain a definition for 'Throw'

您是否知道 DynamicObject 的一种实现,它会因缺少定义而返回 null,或者有关如何创建定义的教程?非常感谢!

【问题讨论】:

    标签: c# dynamic


    【解决方案1】:

    这样的?

    using System;
    using System.Collections.Generic;
    using System.Dynamic;
    
    public class NullingExpandoObject : DynamicObject
    {
        private readonly Dictionary<string, object> values
            = new Dictionary<string, object>();
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            // We don't care about the return value...
            values.TryGetValue(binder.Name, out result);
            return true;
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            values[binder.Name] = value;
            return true;
        }
    }
    
    class Test
    {
        static void Main()
        {
            dynamic x = new NullingExpandoObject();
            x.Foo = "Hello";
            Console.WriteLine(x.Foo ?? "Default"); // Prints Hello
            Console.WriteLine(x.Bar ?? "Default"); // Prints Default
        }
    }
    

    我希望真正的ExpandoObject 比这更复杂,但如果这就是你所需要的......

    【讨论】:

    • 无论values.TryGetValue 中的结果如何,都返回true 以抑制错误。谢谢楼主解答!
    • 很抱歉让这个复活,但它是多年后,这个代码仍然产生两个 RuntimeBinderException 异常。有什么方法可以让这项工作在每次访问期间都不会触发异常?
    • @Anthony:“生产”是什么意思?您的意思是您在调试器中看到了它们,但随后它们被捕获了?
    • @JonSkeet 当您运行这个(或任何类似的)示例时,您没有看到异常抛出并显示在 Visual Studio 的控制台窗口中吗?构建一个基于dynamicobject的框架,发现每次访问你的属性包都会触发一个RubtimeBinderException,这并不好玩;您不仅会产生性能成本,还会使控制台窗口变得混乱。我肯定做错了什么,但是当我看到 Skeetmeister 的代码也这样做时,我想知道动力学出了什么问题。
    • 当我没有静态或动态属性(通过 DynamicObject TryXXX 拦截)时,我可以理解抛出它,但是为了这个目的而构建一个诸如 DynamicObject 之类的类,能够拦截此类呼叫并处理它们,并发现即使您正确处理它仍然会向您抛出异常,这使杰克成为一个悲伤的男孩。没有别的办法吗?
    猜你喜欢
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2013-11-03
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多