C#对象看起来像动态类型

时间:2013-02-19 20:43:25

标签: c# .net dynamic

一直在使用4.0 DLR,并且正在将动态与对象进行比较,并且遇到了这个问题:

代码:

object x = 10;
            Console.WriteLine("x = {0} and is a {1}.\n", x, x.GetType());
            x = (int)x + 3;
            Console.WriteLine("x = {0} and is a {1}.\n", x, x.GetType());
            x = x + "a";
            Console.WriteLine("x = {0} and is a {1}.\n", x, x.GetType());

结果:

  

x = 10并且是System.Int32。

     

x = 13并且是System.Int32。

     

x = 13a并且是System.String。

对我来说,看起来对象试图在运行时(动态)使对象适合类型。但是,如果我没有将x转换为第3行的int,它会给我一个编译器区域,这对于静态类型来说似乎是正确的。但是它允许我向x添加“a”,现在它将其识别为字符串。

我错过了什么?

7 个答案:

答案 0 :(得分:6)

您错过了+运算符在应用于字符串时执行自动转换(通过在操作数上调用.ToString()方法而不是{{1}的实例的事实}))。

答案 1 :(得分:4)

来自C# Language Specification

  

7.8.4加法运算符

     

当一个或两个操作数都是string类型时,预定义的加法运算符会连接操作数的字符串表示。

     
      
  • 字符串连接:

    string operator +(string x, string y);
    string operator +(string x, object y);
    string operator +(object x, string y);
    
         

    binary +运算符的这些重载执行字符串连接。如果字符串连接的操作数是null,则替换空字符串。否则,通过调用从类型对象继承的虚拟ToString方法,将任何非字符串参数转换为其字符串表示形式。如果ToString返回null,则会替换空字符串。

  •   

答案 2 :(得分:2)

请记住变量的类型(即object)与它引用的对象的类型之间存在区别。

允许进行最后一次转化,因为System.String类型定义了一个接受object作为其中一个值并在其上执行自动ToString()的运算符。

运行时或动态操作没有什么好玩的。

答案 3 :(得分:1)

  

对我来说,看起来对象试图在运行时(动态)将对象与类型相匹配。

不是真的:它只是简单地运用.NET object存储任何类型对象的能力。

为了dynamic,变量应该允许你在没有强制转换的情况下调用任何东西,例如

dynamic x = "hello";
dynamic y = x.Substring(0, 2); // The compiler does not complain

如果你尝试使用“普通”object来完成上述技巧,你会收到来自编译器的愤怒信息。然而,使用dynamic会将抱怨推迟到运行时间,此时可能会发生,或者可能根本不会发生。

  

但是它允许我在x中添加“a”,现在它将其识别为字符串。

这是编译器的“魔力”:它知道objectToString,并自动为您插入呼叫。

答案 4 :(得分:1)

由于C#中的所有类型都派生自object类型,因此它可以存储任何类型

object x = 10;
x = x + "a";

编译器实际上做了什么。由于object具有.ToString(),因此当您使用+时,编译器会自动调用它。

即使我们查看 IL 代码,

  .locals init ([0] object x)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  box        [mscorlib]System.Int32
  IL_0008:  stloc.0
  IL_0009:  ldloc.0
  IL_000a:  ldstr      "a"
  IL_000f:  call       string [mscorlib]System.String::Concat(object,
                                                              object)

String.Concat方法的返回值为值的string表示。

来自 C# 5.0 Specification

  
      
  • 字符串连接:

    string operator +(string x, string y);
    string operator +(string x, object y);
    string operator +(object x, string y);
    
         

    binary +运算符的这些重载执行字符串连接。如果字符串连接的操作数是null,则替换空字符串。否则,通过调用从类型对象继承的虚拟ToString方法,将任何非字符串参数转换为其字符串表示形式。如果ToString返回null,则会替换空字符串。

  •   

答案 5 :(得分:0)

C#中的所有内容都来自objectintstringchar等都可以。

执行此操作时:

object x = 10;

您正在创建一个变量x,然后将其初始化为整数值10.该值为int,它只是boxed到对象中。

当您将x作为int投射时,您unboxing就是它的实际类型。

查看Boxing and Unboxing

的本指南

答案 6 :(得分:0)

c#上的所有数据类型都继承自" object"所以任何操作的基本行为都取决于操作员和操作员。另一个对象