• Dynamic


    在阅读《CLR via C# (第三版)》第132页看到dynamic这个类型,感觉挺有用的。

    记录下来日后查用以及跟园友们分享,内容如下:

        为了方便开发人员使用反射或者与基本组件通信,C#编译器允许将一个表达式的类型标记为 dynamic。还可以将一个表达式的结果放到一个变量中,并将变量的类型标记为dynamic。然后,可以用这个 dynamic 表达式/变量调用一个成员,比如字段、属性/索引器、方法、委托以及一元/二元/转换操作符。代码用 dynamic 表达式/变量来调用一个成员时,编译器会生成特殊的 IL 代码来描述所需的操作。这种特殊的代码成为 payload(有效载荷)。在运行时,payload 代码根据当前由 dynamic 表达式/变量引用的对象的实际类型来决定具体执行的操作。

    以下代码对此进行了演示:

    using System;
     
    internal static class DynamicDemo
    {
        public static void Main()
        {
            for (int i = 0; i < 2; i++)
            {
                dynamic arg = (i == 0) ? (dynamic)5 : (dynamic)"A";
                dynamic result = Plus(arg);
                M(result);
            }
        }
     
        private static dynamic Plus(dynamic arg)
        {
            return arg + arg;
        }
     
        private static void M(int n)
        {
            Console.WriteLine("M(int):" + n);
        }
     
        private static void M(string s)
        {
            Console.WriteLine("M(string):" + s);
        }
    }

     

    以上代码是经过了测试的,如果在编译过程中出现错误,可能缺少引用,比如:Microsoft.CSharp

    ------------------------------------------------------------

    执行 Main 方法时,会得到以下输出:

    M(int):10

    M(string):AA

    为了理解发生的事情,让我们先来研究以下 Plus 方法。这个方法将参数的类型声明为 dynamic。在方法内部,实参被作为二元+操作符的两个操作数使用。由于 arg 是 dinamic ,所以C#编译器会生成 payload 代码,以便在运行时检查 arg 的实际类型,并决定 + 操作符实际要做的事情。

    第一次调用Plus时,传递的是5(一个int),所以Plus向它的调用者返回值10(也是一个int)。结果放到result变量(声明为 dynamic 类型)中。然后调用M方法,将 result 传给它。针对对 M 的调用,编译器会生成 payload 代码,以便在运行时检查传给M的值的实际类型,并决定应该调用 M 方法的哪个重载版本。在 result 包含一个 int 的前提下,调用的是获取一个 int 参数的 M 重载。

    第二次调用Plus时,传递的是"A"(一个string),所以 Plus 会将 "AA" ("A"和它自己的连接的结果)传回它的调用者,后者将这个结果放到 result 变量中。然后,再次调用 M 方法,将 result 传给他。 这一次, payload 代码判断出传给 M 的值的实际类型是 String , 所以会调用获取一个 String 参数的 M 重载。

    --------------------------------------

    以及关于更多的 dynamic 的说明以及实现过程,这里就不做更多的介绍了,园友们可以参考《CLR via C# (第三版)》第133页,或者查下MSDN文档吧

     
    分类: C#
    标签: C#Dynamic
  • 相关阅读:
    在宏块级冗余可调的多描述视频编码算法方面取得进展(转载)
    C++单例模式
    C++手动实现库函数
    C#操作java平台生成的公钥
    C++之位操作符
    Windows 8 应用栏
    Windows 8 本地数据存储
    Win8的页面缓存
    操作符sizeof
    three.js结合geoJson绘制中国地图
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2526179.html
Copyright © 2020-2023  润新知