繁体   English   中英

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

[英]C# object looks like dynamic type

一直在使用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”,现在它将其识别为字符串。

我错过了什么?

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

来自C#语言规范

7.8.4加法运算符

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

  • 字符串连接:

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

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

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

允许最后一次转换,因为System.String类型定义了一个操作符,该操作符接受一个object作为其中一个值并对其执行自动ToString()

运行时或动态操作没有任何有趣的业务。

对我来说,看起来对象试图在运行时(动态)使对象适合类型。

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

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

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

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

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

这是编译器的“魔力”:它知道object有一个ToString ,并自动为你插入调用。

由于C#中的所有类型都是从对象类型派生的,因此它可以存储任何类型

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规范

  • 字符串连接:

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

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

C#中的所有内容都继承自object intstringchar等都可以。

当你这样做:

object x = 10;

你要创建一个变量x ,然后将其初始化为整数值10的值是一个int ,它只是被boxed到对象。

当你将xint你将它unboxing到它的实际类型。

查看本指南的拳击和拆箱

c#上的所有数据类型都继承自“object”,因此任何操作的基本行为都取决于运算符和其他对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM