简体   繁体   English

x.toString() 和 x+"" 的区别

[英]Difference between x.toString() and x+""

Back in college one of my profs.回到大学,我的一位教授。 taught us to just do x + "" as a quick conversion from basic types to strings.教我们只做x + ""作为从基本类型到字符串的快速转换。
I don't remember which class it was in I had him for some Java and C++ courses(I haven't used either for some time now), but I use it in C#/.Net now which is what I'm primarily developing in lately.我不记得它在哪个班级我让他参加了一些 Java 和 C++ 课程(我已经有一段时间没有使用过),但我现在在 C#/.Net 中使用它,这是我主要开发的在最近。

Is there an advantage to using .toString() over +"" for basic types such at int, decimal, float...?对于 int、decimal、float 等基本类型,使用.toString()+""有优势吗? What cases would .toString() be better?什么情况下.toString()会更好?

Note:I was shown .toString() as well, that prof just recommended +"" because it was shorter and I have just done that since then without questioning it.注意:我也看到了.toString() ,那个教授刚刚推荐了+""因为它更短,从那时起我就这样做了,没有质疑它。

Well, as a side note, it depends on what x is.好吧,作为旁注,这取决于 x 是什么。 If x is a primitive in Java, you have to call .toString() using one of its wrappers, like如果 x 是 Java 中的原语,则必须使用其包装器之一调用.toString() ,例如

Integer.toString(x)

I would say using toString() is generally better, because x + "", in at least Java, is saying you want to append the two Strings together.我会说使用 toString() 通常更好,因为 x + "",至少在 Java 中,是说您想将两个字符串附加在一起。

Like in this example:就像在这个例子中:

 public static void main(String[] args)
 {
   int x = 3;
   String s = x + "";   
 }

That ends up, in bytecode, as :最终,在字节码中,如下所示:

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

So it has to create a StringBuilder to append "" and the String value of x together.所以它必须创建一个 StringBuilder 来将 "" 和 x 的 String 值附加在一起。 While the efficiency lost isn't that much, it isn't too much to just use the toString function.虽然损失的效率并不高,但是仅仅使用 toString 函数并没有太多。

Compare with using toString:与使用 toString 进行比较:

 public static void main(String[] args)
 {
   int x = 3;
   String s = Integer.toString(x); 
 }

Which ends up as:最终结果为:

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

And although it might just be my opinion, using .toString reflects what you actually want -- you want the String value of x, while using x + "" is kind of a hack and says -- I want the String value of x concatenated with "".虽然这可能只是我的意见,但使用 .toString 反映了你真正想要的——你想要 x 的字符串值,而使用 x + "" 是一种黑客并说——我想要 x 的字符串值连接和 ””。

Side Note: I can't speak on the intermediate bytecode C# would emit, but I imagine something similar to this.旁注:我不能谈论 C# 会发出的中间字节码,但我想像这样的东西。 Plus, with C#, you can just call .ToString() on your value types just as easily as reference types, so I think my advice would apply the same.另外,使用 C#,您可以像引用类型一样轻松地对值类型调用 .ToString(),所以我认为我的建议也适用。

Honestly, I consider that kind of weird advice.老实说,我认为这种奇怪的建议。

I can't speak to every specific case, but in general what x + "" will do in C# (which should depend on the existence of an overloaded + operator for either the type of x or string ) is call something like string.Concat(x, "") which in turn will invoke x.ToString anyway.我不能谈论每个特定情况,但一般来说x + ""在 C# 中会做什么(这应该取决于xstring类型的重载+运算符的存在)调用类似string.Concat(x, "")东西string.Concat(x, "")无论如何都会调用x.ToString

In the typical case, this just means that x + "" has the overhead of one more method call than x.ToString .在典型情况下,这仅意味着x + ""x.ToString多一个方法调用的开销。 When x is a variable of some value type, however, this can also cause the value of x to be boxed unless an overload for + exists specifically for the type of x (this might be considered a useless point to make, as x will also be boxed in a call to ToString if its type has not overridden that method; this strikes me aa bit rarer, but it most assuredly does happen).x是某个值类型的变量,但是,这也导致的值x要被装箱,除非用于过载+为的类型具体地存在x (这可能被认为是无用的点,使作为x将如果ToString的类型没有覆盖该方法,则在对ToString的调用中被装箱;这让我感到有点罕见,但它肯定会发生)。

These are fairly trivial differences, of course.当然,这些都是相当微不足道的差异。 The real difference between these two approaches is that of readability;这两种方法的真正区别在于可读性。 in my experience, x + "" is not very idiomatic in .NET and so I would be inclined to avoid it.根据我的经验, x + ""在 .NET 中不是很惯用,所以我倾向于避免它。 That said, it could just be that it isn't common in the slice of the .NET world I inhabit, while there could be plenty of .NET developers out there who do it.也就是说,这可能只是在我所居住的 .NET 世界中并不常见,而可能有很多 .NET 开发人员在那里这样做。

I will point out that while in Java, perhaps you had to write the unwieldy Integer.toString(x) for variables x of primitive types like int , in C# and in .NET in general all types (including so-called "primitive" ones) inherit from object and so have the method ToString (along with GetType and GetHashCode ) available to them.指出的是,虽然在 Java 中,也许您必须为原始类型的变量x编写笨拙的Integer.toString(x) ,例如int ,在 C# 和 .NET 中一般所有类型(包括所谓的“原始”类型) ) 从object继承,因此可以使用ToString方法(以及GetTypeGetHashCode )。

In Java, for primitive types ( int , double , etc.) you cannot write .toString() because the types aren't objects.在 Java 中,对于原始类型( intdouble等),您不能编写.toString()因为这些类型不是对象。 This means that your options are either to write something like这意味着您可以选择编写类似

x + "";

or to use或使用

Integer.toString(x);

In C++, you cannot use x + "" to do this sort of conversion, since this will be treated as pointer arithmetic and will give you a bad pointer.在 C++ 中,您不能使用x + ""进行这种类型的转换,因为这将被视为指针算术并且会给您一个错误的指针。 Using something like boost::lexical_cast is the preferred way to do the conversion.使用boost::lexical_cast类的东西是进行转换的首选方法。

And... I know nothing about C#, so I won't comment on it.而且...我对C#一无所知,所以我不会评论它。 :-) :-)

There are no advantages or disadvantages of using x+"" .使用x+""没有优点或缺点。 toString is the method of Object type which implicitly called every time you add any object to string. toStringObject类型的方法,每次向字符串添加任何对象时都会隐式调用。

You can always override this method in your class if you'd like.如果您愿意,您始终可以在您的课程中覆盖此方法。

Because strings are immutable, x+"" invokes two functions: x.toString() and StringBuffer.append() (in Java, at least).因为字符串是不可变的,所以x+""调用两个函数:x.toString() 和 StringBuffer.append()(至少在 Java 中)。 I imagine most good JITs would simply turn that into a single function call, x.toString(), but I couldn't be sure without actually testing.我想大多数优秀的 JIT 都会简单地将其转换为单个函数调用 x.toString(),但如果不进行实际测试,我无法确定。

It doesn't matter, really.没关系,真的。 It is very very unlikely this will cause any performance problems whatsoever.这极不可能导致任何性能问题。 So it remains a matter of personal style.所以这仍然是个人风格的问题。 Use whatever you or your team is comfortable with.使用您或您的团队感到满意的任何东西。

In Java,在爪哇,

In addition to working with primitive types, x+"" also works with null .除了使用原始类型, x+""也适用于null Where x.toString() throws a NullPointerException , x+"" returns "null" .其中x.toString()抛出NullPointerExceptionx+""返回"null" Whether that is better or not is up to you, but it is a difference.这是否更好取决于你,但这是一个区别。

In C# I would completely disregard this advice in favor of something more declarative such as using .ToString directly.在 C# 中,我会完全无视这个建议,转而使用更具声明性的东西,例如直接使用.ToString

The only potential advantage this syntax provides you is it will create an empty string if x is null .此语法为您提供的唯一潜在优势是,如果xnull ,它将创建一个空字符串。 I would favor an extension method if this is considered an advantage in your code.如果这被认为是您代码中的优势,我会赞成使用扩展方法。

public static string NullSafeToString<T>(this T value) where T : class {
  return value == null ? "" : value.ToString();
}

The other reason to avoid this is because it can create precedence confusion.避免这种情况的另一个原因是因为它会造成优先级混淆。 For example do you know exactly what the value of z is in the following scenario without the use of reference materials?例如,在不使用参考资料的情况下,您是否确切知道以下场景中z的值?

int x = 42;
int y = 15;
string z = x + y + "";

Now same question with the following现在与以下相同的问题

int x = 42;
int y = 15;
string z = x + y.ToString();

The latter is more likely to be understood at a glance by the average developer who hasn't taken the time to memory C# operator precedence.对于没有花时间记忆 C# 运算符优先级的普通开发人员,后者更有可能一目了然。 Hence I would prefer it because it has a lesser chance of being misunderstood.因此我更喜欢它,因为它被误解的可能性较小。

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

相关问题 C#-x.ToString(“ D”)和x.ToString()之间有什么区别,其中x是int类型? - C# - is there any difference between x.ToString(“D”) and x.ToString(), where x is type int? 实体框架不支持 x.ToString() ! - x.ToString() is not supported by the entity framework! 解释x =&gt; x.ToString()//简化这么多的调用 - Explain x => x.ToString() //simplify so many calls 如何将x.ToString()传递给期望对象类型的方法,而不仅仅是x阻止拳击? - How passing in x.ToString() into a method which is expecting an object type as opposed to just x prevent boxing? 之间的差是X和X _ - Difference between is X and is X _ 为什么C#编译器不能隐式地推断`Foo foo =(int x)=&gt; x.ToString();`对于delagate类型`静态委托R Foo <I, R> (我);`? - Why cannot C# compiler implicitly infer `Foo foo = (int x) => x.ToString();` for the delagate type `static delegate R Foo<I, R>(I i);`? “ 1 &lt;&lt; x”和“ pow(2,x)”有什么区别? - What is the difference between “1 << x” and “pow(2, x)”? !(x is null) 和 x is object 之间有区别吗 - Is there a difference between !(x is null) and x is object x是null和ReferenceEquals(x,null)之间有区别吗? - Is there a difference between x is null and ReferenceEquals(x, null)? “x 为空”和“x == null”有什么区别? - What is the difference between “x is null” and “x == null”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM