微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 为什么我不能在从DynamicObject继承的对象上使用GetType().GetProperty()?

我正在尝试使用反射从动态类中检索字段或属性,但是当我使用Getfield或GetProperty调用动态对象时,它永远不会找到该字段,也不会输入任何动态object.Try *方法.

不知道为什么这不起作用.net4.

请参阅下面的testdyn动态测试类.

我这样称呼它:

dynamic td = new testdyn();
        td.SendDebugEvent += new DebugDelegate(debug);
        td.test();

获得这些结果:

one = -1 
two = -1 
fiddle = -1 
test = -1 
set: fiddle = 241827974 
fiddle = -1

期待看到

one = 1
two = 2
fiddle = 3
test = -1
set: fiddle = 241827974
fiddle = 241827974

我究竟做错了什么?

注意:如果我调用’td.fiddle’它确实有效…但是你不知道创建类的名称但你知道它可以访问它似乎很奇怪吗?

从这篇文章看来,动态对象可能不支持反射,因为它实现了idynamicMetaobjectprovider

How do I reflect over the members of dynamic object?

问题是此代码正由使用反射的外部应用程序使用.

如果你有想法,请告诉我.

代码如下.

public delegate void DebugDelegate(string msg);
 public class testdyn : System.Dynamic.DynamicObject
    {
        List<string> items = new List<string>(new string[] { "one","two","fiddle","my","lou" });
        List<int> vals = new List<int>( new int[] { 1,2,3,5,8 });

        public event DebugDelegate SendDebugEvent;
        void debug(string msg)
        {
            if (SendDebugEvent!=null)
                SendDebugEvent(msg);
        }

        public void set(string name,int v)
        {
            var idx = items.IndexOf(name);
            if (idx < 0)
                return;
            vals[idx] = v;
            debug("set: " + name + " = " + v);
        }

    int get(string name)
    {
        object o = null;
        var t = GetType();
        try {
        o = t.GetProperty(name).GetValue(this,null);
        int v = (int)o;
        return v;
        } catch 
        {
            try
            {
                var f = t.GetField(name);
                o = f.GetValue(this);
                return (int)o;
            }
            catch 
            { 

            }
        }
        return -1;
    }

        string g(string name) { return name+" = "+get(name).ToString(); }
        Random r = new Random();
        public void test() { test(string.Empty); }
        public void test(string mytmp)
        {
            var t = GetType();
            // do some reads
            debug(g("one"));
            debug(g("two"));
            debug(g("fiddle"));
            debug(g("test"));
            // do some sets
            set("fiddle",r.Next());
            // they should change
            debug(g("fiddle"));
        }

        public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder,object[] args,out object result)
        {
            debug("got invoke member");
            return base.TryInvokeMember(binder,args,out result);
        }

        public override bool TrySetMember(System.Dynamic.SetMemberBinder binder,object value)
        {
            debug("got setmember");
            return base.TrySetMember(binder,value);
        }

        public override bool TryGetIndex(System.Dynamic.GetIndexBinder binder,object[] indexes,out object result)
        {
            debug("got getindex");
            return base.TryGetIndex(binder,indexes,out result);
        }

        public override bool TryGetMember(System.Dynamic.GetMemberBinder binder,out object result)
        {
            // get index of column value trying to be retrieved
            var idx = items.IndexOf(binder.Name);
            // default to empty
            result = string.Empty;
            // return error if we can't find
            if (idx < 0)
            {
                return base.TryGetMember(binder,out result);
            }
            // get result
            result = vals[idx];
            return true;
        }

        public override bool TryInvoke(System.Dynamic.InvokeBinder binder,out object result)
        {
            debug("got invoke");
            return base.TryInvoke(binder,out result);
        }



        public override bool TryCreateInstance(System.Dynamic.CreateInstanceBinder binder,out object result)
        {
            debug("got create instance");
            return base.TryCreateInstance(binder,out result);
        }

        public override IEnumerable<string> GetDynamicmemberNames()
        {
            debug("got member names");
            return items.ToArray();
        }
    }

解决方法

反射对动态属性不起作用(尽管如果实现 ICustomTypeProvider,可能会有.net4.5例外)

我写了一个名为ImpromptuInterface的开源DLR瑞士军队knive框架(在nuget中可用).在其中我有一个静态方法,旨在桥接动态属性,使用反射来动态访问属性的外部代码的确切原因. Impromptu.ActLikeProperties(此对象originalDynamic,IDictionary< string,Type> propertySpec)ActLikeProperties.

问题是你需要提供一个属性名称字典&将类型返回到我的方法,然后将结果传递给外部api,我的方法通过使用发出的代理包装DynamicObject来工作,该代理使用dlr将字典中描述的属性调用从它的静态定义转发到动态类型.

td.ActLikeProperties(new Dictionary<string,type>{{"one":typeof(int)},{"two":typeof(int) },{"fiddle":typeof(int) },{"test":typeof(int) }});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐