我曾经模拟VAR VS Dynamic
变量,后来我想到了这个:
dynamic s = 2;
var w = "";
var d1 = s + " " + "dynamic test 1";
var d2 = s + 'd' + ' ' + "dynamic test 2";
String d3 = s + 'k' + ' ' + "dynamic test 2";
var d4 = 'd' + "dynamic test 2";
简化:
我的问题是:
为什么字符d
和k
变成了一个数字,而d4变量中的d
仍然保留在自己的值d
上?
答案 0 :(得分:4)
执行从左到右完成。 因此,首先添加整数然后再添加字符类型将字符转换为整数,然后将其输出附加到字符串。
对于d4,因为在开始时没有整数,所以在追加之前字符被字符串转换为字符串。
说明:
the integer value of 'd' is 100
the value of ' ' is 32
Hence 2 + 100 + 32 = 134.
感谢Paulf提出建议
感谢Corak详细解释。 将其添加到答案中,以免错过。
你有一个int值(2)和一个char值('d')。您想要将它们一起添加。预期的结果是什么? “2d”将是一个字符串,因此既不是int也不是char。对于大多数人来说,这是出乎意料的,所以这并不好。还有什么可能发生的? 'd'可以被2增加。所以结果可能是'f'。但这只适用于极少数的int值。所以决定,int加char会得到int,取char的数值。这几乎适用于int和char的每个组合,因此这是所选择的行为。
另一方面,你有一个char值('d')和一个字符串值(“test”)。您想要将它们一起添加。预期的结果是什么?在int + char中获取char的数值将导致“100test”,这将是非常意外的。此外,object + string(或string + object)的标准行为是隐式将其转换为object.ToString()+ string。并且'd'.ToString()将是“d”(字符串值!)。所以'd'.ToString()+“test”会产生“dtest”,这也是预期的行为。赢得胜利。 ^ _ ^
答案 1 :(得分:3)
因为运算符的优先级和+
运算符的选定重载。当你看这一行时:
var d2 = s + 'd' + ' ' + "dynamic test 2";
对于第一个+
运算符,双方都有int
和char
。这里选择了加法运算符的重载int operator +(int x, int y);
,它将添加数字和字符(它被隐式转换为int,因为在窗帘后面它具有'd'
的数字表示)。在那里你得到一个int
。
PaulF提供了指向char:
的documentation链接Char对象的值是16位数字(序数)值。
这就是结果是数字的原因。
第二个+
运算符的处理方式相同。
第三个+
运算符具有另一个字符串,因此编译器在ToString
变量上隐式调用int
方法,并选择另一个加法运算符的重载,即:string operator +(object x, string y);
连接两者。
您现在可以使用( )
确定优先级。在这一行:
var d2 = s + ('d' + (' ' + "dynamic test 2"));
这里将首先评估第三个+
运算符,因此将进行串联重载。结果是一个字符串。第二个运算符将在右侧再次遇到一个字符串,因此它将再次出现相同的上下文,并且将再次调用ToString()
方法并且char
(变成一个字符串)将是级联。当再次到达第一个运算符时,将调用ToString()
方法(现在在int
上,变成一个字符串)。
This post可能会给予进一步的帮助
修改强>
以下是overview over all possible Addition operator overloads
通常,数据类型的选择取决于以下方式:
对于x + y形式的操作,应用二元运算符重载决策Section 7.2.4来选择特定的运算符实现。操作数将转换为所选运算符的参数类型,结果的类型是运算符的返回类型。
字符串连接的文档说明:
当一个或两个操作数的类型为字符串时,预定义的加法运算符会连接操作数的字符串表示形式。
当一个或两个操作数的类型为字符串时,binary +运算符执行字符串连接。
答案 2 :(得分:2)
为了避免此类错误(添加整数 s
和字符 d
会导致{ {1}})使用字符串插值(或格式化):
s + (int) 'd'
编辑:如果是C#5.0-不支持字符串插值,请尝试使用格式:
dynamic s = 2;
var w = "";
var d1 = $"{s} dynamic test 1"; // s followed by space and dynamic test 1
// I've preserved 'd' and 'k' to show absence of the errors
// More natural code is
// var d2 = $"{s} d dynamic test 2";
var d2 = $"{s} {'d'} dynamic test 2"; // s followed by space then 'd' character ...
String d3 = $"{s}{'k'} dynamic test 2";
var d4 = $"{'d'} dynamic test 2";
...
不要连接字符串:
var d1 = string.Format("{0} dynamic test 1", s);
var d2 = string.Format("{0} {1} dynamic test 2", s, 'd');
String d3 = string.Format("{0}{1} dynamic test 2", s, 'k');
var d4 = string.Format"{0} dynamic test 2", 'd');
可以不同的操作 - 添加和连接)答案 3 :(得分:0)
如果我是对的,就像ASCII一样,每个字母对应一个数字