[英]C# - is there any difference between x.ToString(“D”) and x.ToString(), where x is type int?
[英]Difference between x.toString() and x+""
回到大学,我的一位教授。 教我们只做x + ""
作为从基本类型到字符串的快速转换。
我不记得它在哪个班级我让他参加了一些 Java 和 C++ 课程(我已经有一段时间没有使用过),但我现在在 C#/.Net 中使用它,这是我主要开发的在最近。
对于 int、decimal、float 等基本类型,使用.toString()
比+""
有优势吗? 什么情况下.toString()
会更好?
注意:我也看到了.toString()
,那个教授刚刚推荐了+""
因为它更短,从那时起我就这样做了,没有质疑它。
好吧,作为旁注,这取决于 x 是什么。 如果 x 是 Java 中的原语,则必须使用其包装器之一调用.toString()
,例如
Integer.toString(x)
我会说使用 toString() 通常更好,因为 x + "",至少在 Java 中,是说您想将两个字符串附加在一起。
就像在这个例子中:
public static void main(String[] args)
{
int x = 3;
String s = x + "";
}
最终,在字节码中,如下所示:
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: new #2; //class java/lang/StringBuilder
5: dup
6: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
9: iload_1
10: invokevirtual #4; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: ldc #5; //String
15: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
21: astore_2
22: return
所以它必须创建一个 StringBuilder 来将 "" 和 x 的 String 值附加在一起。 虽然损失的效率并不高,但是仅仅使用 toString 函数并没有太多。
与使用 toString 进行比较:
public static void main(String[] args)
{
int x = 3;
String s = Integer.toString(x);
}
最终结果为:
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iload_1
3: invokestatic #2; //Method java/lang/Integer.toString:(I)Ljava/lang/String;
6: astore_2
7: return
虽然这可能只是我的意见,但使用 .toString 反映了你真正想要的——你想要 x 的字符串值,而使用 x + "" 是一种黑客并说——我想要 x 的字符串值连接和 ””。
旁注:我不能谈论 C# 会发出的中间字节码,但我想像这样的东西。 另外,使用 C#,您可以像引用类型一样轻松地对值类型调用 .ToString(),所以我认为我的建议也适用。
老实说,我认为这种奇怪的建议。
我不能谈论每个特定情况,但一般来说x + ""
在 C# 中会做什么(这应该取决于x
或string
类型的重载+
运算符的存在)调用类似string.Concat(x, "")
东西string.Concat(x, "")
无论如何都会调用x.ToString
。
在典型情况下,这仅意味着x + ""
比x.ToString
多一个方法调用的开销。 当x
是某个值类型的变量,但是,这也导致的值x
要被装箱,除非用于过载+
为的类型具体地存在x
(这可能被认为是无用的点,使作为x
也将如果ToString
的类型没有覆盖该方法,则在对ToString
的调用中被装箱;这让我感到有点罕见,但它肯定会发生)。
当然,这些都是相当微不足道的差异。 这两种方法的真正区别在于可读性。 根据我的经验, x + ""
在 .NET 中不是很惯用,所以我倾向于避免它。 也就是说,这可能只是在我所居住的 .NET 世界中并不常见,而可能有很多 .NET 开发人员在那里这样做。
我要指出的是,虽然在 Java 中,也许您必须为原始类型的变量x
编写笨拙的Integer.toString(x)
,例如int
,在 C# 和 .NET 中一般所有类型(包括所谓的“原始”类型) ) 从object
继承,因此可以使用ToString
方法(以及GetType
和GetHashCode
)。
在 Java 中,对于原始类型( int
、 double
等),您不能编写.toString()
因为这些类型不是对象。 这意味着您可以选择编写类似
x + "";
或使用
Integer.toString(x);
在 C++ 中,您不能使用x + ""
进行这种类型的转换,因为这将被视为指针算术并且会给您一个错误的指针。 使用boost::lexical_cast
类的东西是进行转换的首选方法。
而且...我对C#一无所知,所以我不会评论它。 :-)
使用x+""
没有优点或缺点。 toString
是Object
类型的方法,每次向字符串添加任何对象时都会隐式调用。
如果您愿意,您始终可以在您的课程中覆盖此方法。
因为字符串是不可变的,所以x+""
调用两个函数:x.toString() 和 StringBuffer.append()(至少在 Java 中)。 我想大多数优秀的 JIT 都会简单地将其转换为单个函数调用 x.toString(),但如果不进行实际测试,我无法确定。
没关系,真的。 这极不可能导致任何性能问题。 所以这仍然是个人风格的问题。 使用您或您的团队感到满意的任何东西。
在爪哇,
除了使用原始类型, x+""
也适用于null
。 其中x.toString()
抛出NullPointerException
, x+""
返回"null"
。 这是否更好取决于你,但这是一个区别。
在 C# 中,我会完全无视这个建议,转而使用更具声明性的东西,例如直接使用.ToString
。
此语法为您提供的唯一潜在优势是,如果x
为null
,它将创建一个空字符串。 如果这被认为是您代码中的优势,我会赞成使用扩展方法。
public static string NullSafeToString<T>(this T value) where T : class {
return value == null ? "" : value.ToString();
}
避免这种情况的另一个原因是因为它会造成优先级混淆。 例如,在不使用参考资料的情况下,您是否确切知道以下场景中z
的值?
int x = 42;
int y = 15;
string z = x + y + "";
现在与以下相同的问题
int x = 42;
int y = 15;
string z = x + y.ToString();
对于没有花时间记忆 C# 运算符优先级的普通开发人员,后者更有可能一目了然。 因此我更喜欢它,因为它被误解的可能性较小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.