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

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

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新特性(三)

 

示例代码

目录
相关文章
|
存储 缓存 分布式计算
如何设计歌曲音频指纹索引系统
## 目录 * 音频指纹是什么 * 音频指纹使用场景 * 音频指纹检索主流程 * 指纹检索原理 * 索引检索方案选型 * 机器成本 * 性能考虑 * 如何增量DUMP * 指纹HASH冲突问题 * HASH冲突解决方案 ## 音频指纹是什么 音频指纹技术是指通过特定的算法将一段音频中独一无二的数字特征以标识符的形式提取出来,用于识别海量的声音样本或跟踪定
如何设计歌曲音频指纹索引系统
|
Java
将JDK动态代理生成的类保存为 .class文件System.setProperty(“sun.misc.ProxyGenerator.saveGeneratedFiles“, “true“)无效
将JDK动态代理生成的类保存为 .class文件System.setProperty(“sun.misc.ProxyGenerator.saveGeneratedFiles“, “true“)无效
968 0
将JDK动态代理生成的类保存为 .class文件System.setProperty(“sun.misc.ProxyGenerator.saveGeneratedFiles“, “true“)无效
|
4天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
288 116
|
19天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
6天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
408 38
Meta SAM3开源:让图像分割,听懂你的话
|
13天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
670 220