dynamic基元类型与隐式类型的局部变量var

dynamic代码示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynamicDemo
{
    class Program
    {
        private static dynamic Plus(dynamic arg) { return arg + arg; }
        private static void M(Int32 n) { Console.WriteLine("M(Int32)" + n); }
        private static void M(String s) { Console.WriteLine("M(String)" + s); }

        static void Main(string[] args)
        {
            for (Int32 i = 0; i < 2; i++)
            {
                dynamic arg = (i == 0) ? (dynamic)5 : (dynamic)"A";
                dynamic result = Plus(arg);
                M(result);
            }

            Console.ReadKey();
        }
    }
}

  上述Plus方法,其参数类型为dynamic,在方法内部,实参被作为二元+操作符的两个操作数使用,由于arg是dynamic类型,所以c#编译器会生成payload代码,以便在运行时检查arg的实际类型,并决定+操作符实际要做的事情。

  c#内建的动态求值功能所产生的额外开销是不容忽视的,虽然可以使用动态功能简化语法,但也要看是否值得。毕竟,加载所有这些程序集及额外的内存消耗,会对性能产生额外的影响。如果程序中只有一两个地方需要动态行为,传统的做法或许更高效,也就是调用反射方法(针对托管对象),或者执行手动转型(针对COM对象)。

  var 针对一个方法中的局部变量,c#允许根据初始化表达式的类型推断它的类型,代码示例:

private static void ShowType<T>(T t)
{
    Console.WriteLine(typeof(T));
}

private static void ImplecitlyTypedLocalVariables()
{
    var name = "hac";
    ShowType(name);

    var collection = new Dictionary<String, Single>() { { ".NET", 4.0f } };
    ShowType(collection);

    foreach (var item in collection)
    {
        ShowType(item);
    }
}

二者区别:

  用var声明一个局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型。var关键字只能声明方法内部的局部变量,而dynamic可以用于局部变量,字段和参数。表达式不能转型为var,但能转型为dynamic。必须显示初始化用var声明的变量,但无需初始化用dynamic声明的变量。

原文地址:https://www.cnblogs.com/hachun/p/4530788.html