zoukankan      html  css  js  c++  java
  • 理解C# 4 dynamic(1)

    阅读目录:

    一. 为什么是它们三个

    二. 能够任意赋值的原因

    三. dynamic的用法

    四. 使用dynamic的注意事项

    一. 为什么是它们三个?

    拿这三者比较的原因是它们在使用的时候非常相似。你可以用它们声明的变量赋任何类型的值。

    看看下面的示例:

    var a = 1;
    object b = 1;
    dynamic c = 1;

     你还可以使用关键字为它们赋上更加复杂的类型

    var a = new string[]{"1"};
    object b = new string[]{"1"};
    dynamic c = new string[]{"1"};

    二. 能够任意赋值的原因

     上面的例子中,看起来三者非常相似,但是背后的原理却是非常不同。

    var是C# 3中引入的,其实它仅仅只是一个语法糖. var本身并不是一种类型, 其它两者object和dynamic是类型。

    var声明的变量在赋值的那一刻,就已经决定了它是什么类型。

    所以如果你这样使用,就会有编译错误:

    var a = 1;
    a = "Test";

    object之所以能够被赋值为任意类型的原因,其实都知道,因为所有的类型都派生自object. 所以它可以赋值为任何类型:

    object a = 1;
    a = "Test";

    那么dynamic呢?

    它是C#引入的新类型,它的特点是申明为dynamic类型的变量,不是在编译时候确定实际类型的, 而是在运行时。

    所以下面的代码是能够通过编译的,但是会在运行时报错:

    dynamic a = "test";
    a++;

    上面代码内部处理的过程是怎样的呢?

    首先, dynamic类型赋值为字符串"test", 运行++操作的时候,.net会去寻找当前的赋值类型string中是否支持++操作,发现不支持,出现异常。

    所以,如果这样修改一下,就可以让代码正常运行起来

    dynamic a = "test";
    a = 1;
    a++;

    三. dynamic的用法

    1 直接使用该类型,可以非常方便的插入属性, 方法

    复制代码
    static void Main(string[] args)
    {
        dynamic person = new System.Dynamic.ExpandoObject();
        person.Name = "cary";
        person.Age = 25;
        person.ShowDescription = new Func<string>(() => person.Name + person.Age);
     
        Console.WriteLine(person.Name + person.Age + person.ShowDescription());
        Console.ReadLine();
    }
    复制代码

    枚举所有成员

    foreach (var property in (IDictionary<String, Object>)dynEO)
    {
         Console.WriteLine(property.Key + ": " + property.Value);
    }

    3 简化反射

    常用的处理反射的例子:

    object calc = GetCalculator();
    Type calcType = calc.GetType();
    object res = calcType.InvokeMember( "Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
    int sum = Convert.ToInt32(res);

    使用dynamic之后:

     dynamic calc = GetCalculator();
     int sum = calc.Add(10, 20);

    四,使用dynamic的注意事项

    有了dynamic,.net就以及有了动态类型的优势,但是由于对于dynamic类型的所有操作,都是在运行时确定的,所有错误无法在编译时候出现,使用的时候,就需要非常小心。

    因为dynamic是类型,所以如果函数接受的是确定类型的参数,是不能传入dynamic类型的,这样会有编译错误。比如:

    复制代码
    public int Add(int a, int b){
        return a + b;
    }
    dynamic test1 = 1;
    dynamic test2 = 2;
    Add(test1, test2);
    复制代码

    下面是对上面的例子的修正,谢谢Alan@Net. 大家可以实验一下

    1. #15楼 Alan@Net  2014-02-04 21:30
      为什么我copy你最后一个例子,并没有报错?
    2. #16楼[楼主] JustRun  2014-02-07 08:30
      @Alan@Net
      应该是编译不通过,我待会试试
    3. #17楼[楼主] JustRun  2014-02-08 08:29
      @Alan@Net
      是不会报错,对于普通的类型,int这样的,不会有问题。
      但是如果是对象类型,运行时会报错。

    另外,在我们自己在写函数时,最好不要将dynamic类型作为函数的参数,这就像是使用object作为函数参数一样,会为程序的维护带来后续的麻烦。

    没有人能够确定使用者传入的是什么,而且编译时候不会有问题。如果错误出现在运行时,就有可能是灾难。

  • 相关阅读:
    HDU 5059 Help him
    HDU 5058 So easy
    HDU 5056 Boring count
    HDU 5055 Bob and math problem
    HDU 5054 Alice and Bob
    HDU 5019 Revenge of GCD
    HDU 5018 Revenge of Fibonacci
    HDU 1556 Color the ball
    CodeForces 702D Road to Post Office
    CodeForces 702C Cellular Network
  • 原文地址:https://www.cnblogs.com/webenh/p/7691680.html
Copyright © 2011-2022 走看看