Dynamic 动态类型 和双问号??的使用

1.dynamic关键字用于声明一个动态对象,然后通过该动态对象去调用方法或读写属性。以前我们都是在运行时通过反射,Emit,CodeDom等技术来完成。创建一个dynamic类型的对象需要使用一个特殊的构建器叫ExpandoObject。

            dynamic aehyok = new ExpandoObject();
            aehyok.Name = "aehyok";
            aehyok.Age = "24";
            aehyok.Position = "ASP.NET";
            Console.WriteLine("姓名:" + aehyok.Name + "年龄:" + aehyok.Age + aehyok.Position);
            Console.ReadKey();

通过控制台执行程序可以查看执行结果为:

2.通过动态类型来实现基于duck typing的泛型参数约束。

    public static class Calculator { 
        public static T Add<T>(T t1, T t2)
        { 
            dynamic d1 = t1; 
            dynamic d2 = t2; 
            return (T)(d1 + d2); 
        }
    }

那么通过调用

            int i = Calculator.Add(1, 2);
            double d = Calculator.Add(1.1, 2.2);
            string s = Calculator.Add("abc", "def");
            Console.WriteLine(i + " " + d + " " + s);
            Console.ReadKey();

执行后发现

除了运算符重载,对于普通的方法调用也是适用的。这种方法是一种动态duck typing的泛型参数约束机制,依赖于运行时的方法查找,与模板编译时的检查不同,它需要使用者保证传入的对象符合相应要求。

3.DynamicObject类都通过虚方法virtual去“实现”了接口中所有的方法,只要继承了这个类,读者可以根据需要“任意”动态覆盖你要的方法)。

    public class DynamicAnimal : DynamicObject
    {
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            bool success = base.TryInvokeMember(binder, args, out result);
            //如果方法不存在,请将result 这个out参数赋值为null            
            if (!success)
            {
                result = null;
            }
            //如果这个地方返回false 将会引发异常            
            return true;
        }
    }

继承此类被进行简单的实现。

接下来我们创建了两个类。

    public class Duck : DynamicAnimal
    {
        public string Quack()
        {
            return "鸭子嘛,就是Quack吧。";
        }
    }

    public class Human : DynamicAnimal
    {
        public string Talk()
        {
            return "人类是用Talk,而不是Quack";
        }
    }

通过控制台应用程序进行调用

        static void Main(string[] args)
        {
            var duck = new Duck();
            var cow = new Human();
            Console.WriteLine("鸭子是Quack");
            Console.WriteLine(DoQuack(duck));
            Console.WriteLine("人类是talk");
            Console.WriteLine(DoQuack(cow));
            Console.ReadKey();

        }

        public static string DoQuack(dynamic animal)
        {
            string result = animal.Quack();
            return result ?? "...人类当然不会鸭叫...";
        }
    }

当然我们在下面定义了一个静态的方法传入dynamic类型,这里需要去调试就会明白。其中还有一个双问号

4.双问号的作用:

双问号(??)是一个单元运算符,那么其左右两边数据类型必须是相同类型或能隐形转换类型的。它表示的意思是,首先检测左边的值,若其为Null,那么整个表达式取值为右侧的值,否则为左侧的值。

参考以下链接:C#4.0和VS2010新特性(三)

示例代码

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码农分享

原型模式(Prototype)

原型模式的结构 原型模式包含以下3个角色: •Prototype(抽象原型类) •ConcretePrototype(具体原型类) •Client(客户...

11830
来自专栏菩提树下的杨过

Silverlight与WPF中BeginInvoke的差异

Silverlight/WPF中,如果要在多线程中对界面控件值做修改,用Dispatcher对象的BeginInvoke方法无疑是最方便的办法 ,见:温故而知新...

23680
来自专栏大内老A

由for V.S. for each想到的

一直想写一系列如何提高Performance和Scalability的文章,把我的相关经验和所知道的相关的技巧同大家分享。前一阵在园子里有一篇讨论for eac...

19680
来自专栏程序你好

理解C#语言中相等Equality 和唯一 Identity

10820
来自专栏飞扬的花生

集合中随机取不重复的索引

有时候希望从一个集合中随机取n个元素不重复 那么就取到这n个数字的索引 public static int[] GetRandomArray(int Numb...

33480
来自专栏技术博客

Asp.net MVC后台 XML、DataTable、DataSet之间的数据转换

  上面的方法只是将XMl字符串读入到DataSet中,然后再冲DataSet中查找先前定义过的DataTable即可。

15020
来自专栏技术博客

一步一步学Linq to sql(一):预备知识

  Linq to sql(或者叫DLINQ)是LINQ(.NET语言集成查询)的一部分,全称基于关系数据的 .NET 语言集成查询,用于以对象形式管理关系数据...

9810
来自专栏二进制文集

JSON Java 解析

要使程序可以运行必须引入JSON-lib包——org.json.jar包。综合来看,这个JAR包比较好用。

18820
来自专栏GreenLeaves

C# 字符串操作基本过程(Equals、Compare、EndsWith等处理方法)

42620
来自专栏hbbliyong

C#基础知识回顾-- 反射(3)

获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺...

30160

扫码关注云+社区

领取腾讯云代金券