一直在使用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”,现在它将其识别为字符串。
我错过了什么?
答案 0 :(得分:6)
您错过了+
运算符在应用于字符串时执行自动转换(通过在操作数上调用.ToString()
方法而不是{{1}的实例的事实}))。
答案 1 :(得分:4)
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”,现在它将其识别为字符串。
这是编译器的“魔力”:它知道object
有ToString
,并自动为您插入呼叫。
答案 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#中的所有内容都来自object
。 int
,string
,char
等都可以。
执行此操作时:
object x = 10;
您正在创建一个变量x
,然后将其初始化为整数值10.该值为int
,它只是boxed
到对象中。
当您将x
作为int
投射时,您unboxing
就是它的实际类型。
答案 6 :(得分:0)
c#上的所有数据类型都继承自" object"所以任何操作的基本行为都取决于操作员和操作员。另一个对象