C# 新特性 dynamic的使用及扩展

个人而言感觉C#的dynamic是一个特别实用的东西,为日常开发工作中的封装,数据传递等带来了很高的可扩展性。

C#4.0中通过对数据类型后期绑定的支持,演化出了dynamic。任何直接声明为这种类型的变量,或者任何在方法参数、方法返回值、实体类属性中声明为dynamic类型的变量,都会在运行时解析成为相对应的原本数据类型,自动地视为后期绑定。

1.个人理解dynamic 类型在方法中的使用情况类似于 泛型T,你需要知道这个dynamic 类型具体是什么类型,有什么属性,从而实现封装等功能的实现。

例如:

    public class TestA
    {
        public string ProA { get; set; }
        public string ProB { get; set; }
    }


    public class TestB
    {
        public string ProA { get; set; }
        public string ProC { get; set; }
    }

在这种情况下,如果我们需要有两个方法。分别接受 TestA的ProA属性,  TestB的ProA属性,实现+"Str"功能,传统的开发代码如下

    public class TestAService
    {

        public string AddStr(TestA testA)
        {
            return testA.ProA + "Str";
        }

    }


    public class TestBService
    {
        public string AddStr(TestB testB)
        {
            return testB.ProA + "Str";
        }

    }

可见,代码的相似程度是极高的,由此,我们可以用dynamic实现,代码如下 

    public class TestCommonService
    {
        public string AddStr(dynamic test)
        {
            return test.ProA + "Str";
        }

    }


2.对于dynamic的另外一种用法是可以实现动态的为某个匿名类实现添加属性,并且赋值功能,如下:

        public ActionResult TestIndex()
        {
            dynamic testDynamic = new ExpandoObject();
            testDynamic.ProA = "ProA";
            TestCommonService testCommonService=new TestCommonService();
            string res = testCommonService.AddStr(testDynamic);
            return View();
        }

dynamic的特性非常有利于我们需要对某一组需要相同特性的数据做处理时的功能实现。
3.对于DynamicObject的扩展可以尝试如下:

    public class SimpleDynamic : DynamicObject
    {

        public Dictionary<string, object> Properties = new Dictionary<string, object>();  //匿名类动态属性的集合

        public void SetProperties(Dictionary<string, object> Properties)     
        {
            this.Properties = Properties;
        }

        Dictionary<string, object[]> Methods = new Dictionary<string, object[]>();
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (!Methods.Keys.Contains(binder.Name))
            {
                Methods.Add(binder.Name, null);
            }
            if (args != null)
            {
                Methods[binder.Name] = args;
            }
            StringBuilder sbu = new StringBuilder();
            foreach (var item in args)
            {
                sbu.Append(item);
            }
            result = sbu.ToString();
            return true;

        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!Properties.Keys.Contains(binder.Name))
            {
                Properties.Add(binder.Name, value.ToString());
            }
            return true;

        }
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {

            return Properties.TryGetValue(binder.Name, out result);
        }
    }
TryInvokeMember方法详见:http://msdn.microsoft.com/zh-cn/library/system.dynamic.dynamicobject.tryinvokemember.aspx

对于dynamic的研究暂时到这里,对于DynamicObject的扩展其实感觉可以应用到数据库层读取的ORM映射中来。稍后会做一下尝试。

 

posted @ 2014-07-02 14:04  曹赫洋  阅读(826)  评论(0编辑  收藏  举报