C #에서 문자열 및 정수 변수를 연결할 때 .ToString ()을 사용해야합니까?


19
int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

내가 사용해야합니까 :

string expression = "Expression: " + a + " + " + b + " = " + sum;

또는

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

그것을 사용하는 것이 좋습니다 ToString()합치 때 stringint?


6
에서 a + "" + b + ""또는 "" + a + b + "", 그것은 중요하지 않습니다 : 그것은 모든 문자열 연결합니다. 에 a + b + ""상관하지 : a그리고 b처음에 추가됩니다.
Tim S.

4
사이드 노트 :에서 VB.NET,이 모호함은 명시함으로써 피할 문자열 연결 연산자 : "Expression: " + a(옵션 엄격한에 포함) 컴파일 타임 오류가 발생합니다 "Expression: " & a문자열 연결을 수행합니다.
Heinzi

첫 번째 코드는 복싱 (Int32와 동일)을 발생시키고 두 번째 코드는 그렇지 않습니다. 두 번째는 분명히 더 빠릅니다.
랜덤 알파벳

답변:


33

ToString 용법

아니요, ToString여기서 사용해서는 안됩니다 .

문자열 연결은 문자열이 아닌 문자열을 자동으로 문자열로 변환하므로 두 변형이 거의 ¹ 동일하다는 것을 의미합니다.

피연산자 중 하나 또는 둘 모두가 문자열 유형 인 경우 사전 정의 된 추가 연산자는 피연산자의 문자열 표시를 연결합니다.

출처 : C # 언어 사양 : 추가 연산자, MSDN .

반면에 첫 번째 것은 (없이 ToString) :

  • 작성하는 것이 더 짧습니다.
  • 읽기가 더 짧습니다.
  • 유지 보수가 쉽고 다음과 같습니다.
  • 문자열을 연결하는 저자의 의도를 정확하게 보여줍니다.

따라서 첫 번째를 선호하십시오.

후드

흥미로운 것은 후드 아래에서 무슨 일이 일어나는지 보는 것입니다. 이를 보는 방법 중 하나는 LINQPad 내에서 IL 코드를 보는 것입니다. 이 프로그램:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

다음 IL로 번역됩니다.

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

저거 봐 System.String.Concat? 즉, 원래 코드도 이와 같이 작성 될 수 있으며 이는 정확히 동일한 IL로 변환됩니다.

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

의 설명서string.Concat(object[]) 를 읽으면 다음을 배울 수 있습니다.

이 메소드 는 해당 오브젝트 의 매개 변수없는 메소드를 호출하여 인수 로 각 오브젝트를 연결 ToString합니다. 구분자를 추가하지 않습니다.

이것은 ToString중복 됨을 의미합니다 . 또한:

String.Empty 배열에서 null 객체 대신 사용됩니다.

피연산자 중 일부가 null 인 경우를 잘 처리합니다 (각주 1 참조).

마지막 예제에서 연결이로 변환되었지만 string.Concat컴파일러 최적화도 강조해야합니다.

var a = "Hello " + "World";

로 번역됩니다 :

ldstr       "Hello World"
stloc.0

반면에 :

var a = string.Concat("Hello ", "World");

로 번역됩니다 :

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

다른 대안들

물론 C #에서 개체의 문자열 표현을 연결하는 다른 방법이 있습니다.

  1. StringBuilder많은 연결 작업을 수행해야 할 때 사용되며 생성 된 중간 문자열 수를 줄이는 데 도움이됩니다. StringBuilder연결을 사용해야하는지 일반 연결을 사용해야하는지 결정 하기가 쉽지 않을 수 있습니다. 프로파일 러를 사용하거나 스택 오버플로에서 관련 답변을 검색하십시오.

    를 사용 StringBuilder하면 코드를 읽고 유지 관리하기가 어렵다는 큰 단점이 있습니다. 귀하의 질문에있는 간단한 경우 StringBuilder, 코드의 가독성에 해를 끼칠뿐만 아니라 성능면에서 쓸모가 없습니다.

  2. string.Join 구분 기호를 추가해야 할 때 사용해야합니다.

    분명히 string.Join빈 분리 문자와 함께 사용 하여 문자열을 연결 하지 마십시오 .

  3. string.Format문자열 템플릿보다 문자열 템플릿을 선호하는 경우 사용할 수 있습니다. kunthet의 답변에서 제안한 것처럼 메시지를 현지화 할 수있는 경우가 있습니다.

    를 사용하면 string.Format몇 가지 단점이 있으므로 다음과 같은 간단한 경우에는 적합하지 않습니다.

    • 단순한 "{0}"자리 표시자를 사용하면 어느 매개 변수가 어디로 가는지 불분명합니다. 실수로 매개 변수를 반대로 바꾸거나 잊어 버리는 경우가 많습니다. 운 좋게도 C # 6은 마침내이 문제를 해결하는 문자열 보간법을 도입 합니다.

    • 런타임 성능이 저하 될 수 있습니다. 물론, 가정하지 않는 string.Format것입니다 항상 느린. 성능이 중요한 경우 두 가지 접근 방식을 측정하고 가정 대신 실제 결과에 따라 더 빠른 접근 방법을 결정하십시오.

    • 코드는 작성하기에 약간 더 길고, 읽기에 더 길고, 유지하기가 더 어렵습니다.


¹ 개체 중 하나가이면 차이가 나타납니다 null. 이 없으면 ToStringa null가 빈 문자열로 바뀝니다. 와 함께 ToStringa NullReferenceException가 발생합니다.


1
정확히 이런 이유로 (예측할 수없는 행동), 문자열을 연결하는 +것은 대부분의 언어에서 나쁜 습관으로 간주됩니다. 이 경우에는을 사용 string.Concat하며 많은 경우 string.Format더 좋습니다. 사용하는 것은 확실히 Pythonic이 아니며 +PEP 3101 %은 권장하지 않기 때문에 권장하지 않습니다 str.format.
Arda Xi

2
null실제로 "잘 처리" 하기 위해 빈 문자열을 대체 합니까? 글쎄, 그것은 "다음 오류 이력서 이력서"만큼 나쁘지 않습니다 ...
중복 제거기

후드에서 .ToString ()을 호출하지 않고 연결하면 권투가 발생하고 ... Concat(object[])대신 사용됩니다 Concat(string[]). 그래서 "string " + i실제로 동일하지 않습니다"string " + i.ToString()
랜덤 알파벳

@RandomAlphabets : 유효한 포인트. 그러나 차이점은 단순히 ToString()OP의 코드 위치와 System.String.Concat다른 경우의 구현입니다. 따라서 답은 여전히 ​​유효합니다. 유익하지 않은 코드를 작성하지 마십시오.
Arseni Mourzenko

15

대신 문자열 포맷터를 사용해야합니다. 숫자를 문자열 표현 또는 현지화로 쉽게 포맷 할 수 있습니다. 예 :

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

MSDN에 대한 추가 정보 .

그러나 문자열 포맷터는 문자열 연결보다 읽기 어렵고 성능도 떨어집니다.


6
이 옵션이 더 좋은 이유를 설명해 주시겠습니까?
세계 엔지니어

@ WorldEngineer : 설명을 업데이트했습니다.
kunthet

12
나는 다른 모든 사람들에 대해 모른다. 그러나 나는 이것을 더 읽기 쉽다. s [n] printf가 이런 종류의 코드에 대한 유일한 현실적인 옵션 인 C와 함께 자랐기 때문일 수 있습니다.
Jules

2
그러나이 방법은 하나가 아닌 세 가지 실수의 원인을 제공합니다. 문자열에 무언가를 추가 할 때 1) 형식 문자열을 변경해야합니다 .2) 목록에 새 매개 변수를 추가하는 것을 잊지 않아야합니다 .3) 새 매개 변수를 배치 해야하는 목록에서 올바른 지점을 선택하십시오.
Ruslan

2
C # 6에서 곧 나오는 문자열 보간 기능에 대해 알려주려면 "Expression : \ {a} + \ {b} = \ {sum}"을 작성하여 동일한 결과를 얻습니다. codeproject.com/Articles/846566/…
cwap

-2

+연결 을 사용 하면 자체적으로 String.Concat메소드를 사용 합니다. 문자열 자체는 + 연산자를 노출하지 않습니다.

예를 들면 다음과 같습니다.

int i = 10;
string str = "hello" + i;

로 컴파일됩니다 :

int i = 10;
object o1 = "hello";
object o2 = i; // Note boxing
string str = string.Concat(o1, o2);

직접 전화하면 ToString권투를 피하고 Concat(string, string)과부하를 호출합니다 . 따라서 ToString호출은 충분히 중요하지는 않지만 약간 더 효율적입니다. 더 읽기 쉽다고 생각하는 예를 사용하는 것이 좋습니다.


2
이것은 단순히 이전 답변 에서 설명되고 설명 된 점을 반복하는 것처럼 보입니다 . "문자열 연결은 문자열이 아닌 문자열을 자동으로 문자열로 변환합니다 ..."
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.