zoukankan      html  css  js  c++  java
  • C# 中的动态类型

    应用场景:

    假如你要构建一个人对象,通常情况下应该定义名字,地址,出生年月等。但是在运行中可能会出现你需要使用一些人对象没有包含的字段或者属性。比如还需要学历,婚姻状况等。

    那么如何在运行中构建一个对象,且系统事先不知道该对象有什么属性,支持什么方法。

    在.NET Framework 4.0 中提供了两个类 一个是DynamicObject, 另一个是 ExpandoObject

    DynamicObject

    DynamicObject 基类提供了在运行时为类添加动态功能。如果需要自定义动态对象需要继承此基类。

    DynamicObject 实现IDynamicMetaObjectProvider, 使用这个接口可以在不同的支持CLR 的语言间共享自定义的动态对象,比如在 C# 语言和 VB.NET 语言间共享自定义对象。

    注意:

    1. 不能直接实例化DynamicObject 类,必须从其继承。
    2. 在C# 中,需要使用 dynamic 关键字来使用从DynamicObject继承的类

     

    在继承时,根据需要覆写基类DynamicObject类的相应方法。

    TryGetMember: 动态添加Property 的Get方法

    TrySetMember:  动态添加Property 的 Set方法

    TryInvokeMember: 动态添加方法. 可以把一个方法赋值给委托然后把委托赋值给动态对象的方法名

    还有很有类似的方法,如:TryConvert, TryBinaryOperation, TryCreateInstance, TryDeleteIndex,TryGetIndex,TryInvoke,TryUnaryOperation.

    更多信息请阅读:

    http://msdn.microsoft.com/zh-cn/library/system.dynamic.dynamicobject.aspx

     

     

    public class DynamicPerson : DynamicObject
        {
            // Inner Dictionary
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
     
            /// <summary>
            /// If you try to get a value of Property not defined in class, this method is called
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="result"></param>
            /// <returns></returns>
            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                string name = binder.Name.ToLower();
     
                return dictionary.TryGetValue(name, out result);
            }
     
            /// <summary>
            /// If you try to set a value of a property taht is not defined in the class, this method is called
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public override bool TrySetMember(SetMemberBinder binder, object value)
            {
                dictionary[binder.Name.ToLower()] = value;
                return true;
            }
     
            /// <summary>
            /// Try to set a method not defined in the class, this method is called
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="args"></param>
            /// <param name="result"></param>
            /// <returns></returns>
            public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
            {
                dynamic method = dictionary[binder.Name.ToLower()];
                result = method(args);
                return result != null;
            }
        }

     

      public void Run()
            {
                dynamic person = new DynamicPerson();
                person.FirstName = "Dynamic";
                person.LastName = "Property";
                Action<object> action = item => { Console.WriteLine(item.ToString());
                    dynamic person1 = item; Console.WriteLine(person1.FirstName); 
                    Console.WriteLine(person1.LastName); };
     
                person.Show = action;
                person.Show(person);
            }

     

    ExpandoObject

    ExpandoObject 是一个seadled 类 不实现了IDyanmicMetaObjectProvider 接口,不能从其继承。它的使用方式非常的简单:

     public void TestExpandoObject()
            {
                dynamic expandoObject = new ExpandoObject();
                expandoObject.FirstName = "Dynamic";
                expandoObject.LastName = "Property";
     
                expandoObject.Show = (Action<object>)(item =>
                {
                    Console.WriteLine("Output dynamic property in dynamic method");
                    dynamic person1 = item; Console.WriteLine(person1.FirstName);
                    Console.WriteLine(person1.LastName);
                });
     
                expandoObject.Show(expandoObject);
            }

     

    如果需要控制动态对象中德属性的添加和访问,则使该对象派生自DynamicObject是最佳的选择。而对于其他情况使用ExpandoObject则比较方便。

  • 相关阅读:
    HDU-3790 最短路径问题(双重权值)
    Graph (floyd)
    POJ-3259 Wormholes(判断负环、模板)
    HDU-1317 XYZZY
    HDU-1548 A strange lift(单源最短路 或 BFS)
    最小生成树(模板 prim)
    【面试】386- JavaScript 面试 20 个核心考点
    【Koa】385- koa框架的快速入门与使用
    【小程序】384- 如何一人五天开发完复杂小程序(前端必看)
    【React】383- React Fiber:深入理解 React reconciliation 算法
  • 原文地址:https://www.cnblogs.com/xinghuayang/p/2973334.html
Copyright © 2011-2022 走看看