ExpandoObject使用“额外"代码添加属性 [英] ExpandoObject add Property with "extra"-code

查看:300
本文介绍了ExpandoObject使用“额外"代码添加属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了一些关于ExpandoObject的内容,并且可以使用属性,字段,方法对其进行扩展.

I've read some stuff about the ExpandoObject, and that I can expand it with properties,fields,methods.

//that's how to add a property to an ExpandoObject.
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;

但是有时候,添加带有一些额外代码"的属性可能会很方便.

But sometimes, it could be handy to add a property with some "extra-code".

class sample
{
    // a sample field.
    public string sampleString{get;set}
    // a sample property with some "extra code"
    private string s;
    public string sampleExtraString
    { 
         get{return s;}
         set{s=value;Console.WriteLine(s);}
    }
}

现在我的问题是,如何向ExpandoObject添加一个属性,以在例如set 上执行我的Console.WriteLine(s);.

Now my question is, how can I add a property to the ExpandoObject that will execute my Console.WriteLine(s); for example on set.

推荐答案

我认为更好的方法是使用DynamicObject,可以拦截对
方法和属性的调用.
这是一个简单的示例,一个更强大的示例将不使用反射对属性执行设置/获取操作,而是使用reflect.Emit或任何已编译的操作策略.

I think a better approach would be using DynamicObject which you can intercept the calls for
methods and properties.
This is a simple example, a more robust one would not use reflection to perform set/get operations on the property but rather using reflection.Emit or any compiled operation strategy.

public class Sample
{
    public string SampleExtraString { get; set; }
}

public class Factory
{
    public class ExtraPropertyObject<T> : DynamicObject
    {
        private readonly T instance = default(T);
        private readonly Type instanceType = null;

        public ExtraPropertyObject(T instance) {
            this.instance = instance;
            instanceType = instance.GetType();
        }

        public override bool TrySetMember(SetMemberBinder binder, object value) {
            PropertyInfo prop = null;

            if (binder.Name.Equals("SampleExtraString")) {
                Console.WriteLine(value);
            }

            prop = instanceType.GetProperty(binder.Name);

            if (prop != null) {
                try {
                    prop.SetValue(instance, value);
                    return true;
                }
                catch (Exception ex) {

                }
            }

            return false;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result) {
            var prop = instanceType.GetProperty(binder.Name);

            if (prop != null) {
                try {
                    result = prop.GetValue(instance);
                    return true;
                }
                catch (Exception ex) {

                }
            }

            result = null;
            return false;
        }
    }

    public static dynamic CreateInstance<TInstance>() where TInstance : class, new() {
        return new ExtraPropertyObject<TInstance>(new TInstance());
    }

    public static dynamic CreateInstance<TInstance>(TInstance instance) {
        return new ExtraPropertyObject<TInstance>(instance);
    }
}

class Program
{
    static void Main(string[] args) {
        var instance = Factory.CreateInstance<Sample>();
        instance.SampleExtraString = "value";
        Console.WriteLine("Get Operation: {0}", instance.SampleExtraString);
    }
}

这篇关于ExpandoObject使用“额外"代码添加属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆