변수와 인라인 변수가있는 string.format


9

사용하는 장단점은 무엇입니까?

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

string output; 
int i = 10;
output = "the int is " + i;

필자는 항상 후자의 예제를 사용해 왔지만 대부분의 온라인 자습서에서 string.format 예제를 사용하는 것처럼 보입니다. 효율성 측면에서 실제 차이점이 있다고 생각하지 않습니다. 초기 생각은 코더가 변수를 삽입하기 위해 문자열을 계속 끊을 필요가 없다는 것입니다.


8
주된 이유는 프로그램이 다른 언어가 문장을 구성하는 방식을 이해할 필요가 없기 때문에 번역이 훨씬 쉬워지기 때문입니다. 예를 들어, 프랑스어로 된 많은 표현과 구가 영어 번역과 비교하여 앞뒤로 있습니다.
JohnL

답변:


22

프로젝트에서 번역이 중요하다고 생각되면 첫 번째 구문이 실제로 도움이 될 것입니다.

예를 들어 다음이있을 수 있습니다.

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

또한 변수가 해당 구문의 문장에서 항상 같은 위치에있는 것은 아닙니다.

static final string output_yoda = "{1} years {0} has.";

4
object-subject-verb 구문의 예로 Yoda-speak를 사용하면 +1입니다.
Mike Harris

1
C #에는 새로운 옵션이 있습니다 :System.out.println($"{name} is {age} year's old.");
Berin Loritsch


@BerinLoritsch : 불행히도 현지화에는 완전히 사용할 수 없습니다.
Bryan Boettcher

@BryanBoettcher는 이해했지만 OP에서 그들이 달성하려는 것을 말하는 것을 보지 못했습니다.
Berin Loritsch

8

/programming/4671610/why-use-string-format에 대한 첫 번째 답변을 확인하십시오 . 그것은 왜 더 나은지에 대한 내 의견으로는 모든 것을 포함합니다.

또한 각 .NET 어셈블리에는 고유 한 문자열 모음이 포함 된 인턴 풀이 있습니다. 코드가 컴파일되면 코드에서 참조하는 모든 문자열 리터럴이이 풀에 추가됩니다. 다음과 같은 코드가있는 경우 :

"the int is " + i + " and the double is " + d

그것은 수영장에서 2 개의 문자열을 만듭니다.

당신이 가지고 있다면:

"the int is {0} and the double is {1}"

풀에 하나의 문자열 만 있습니다.

좀 더 문자열이 억류 때 알고 복잡하고, 그렇지 않은 경우 컴파일러는 예를 들어 확인 ... 때로는 구금 할 필요가 있습니다 문자열을 검출하는 몇 가지 정보를 가지고 있기 때문에되는 이 글 이에 더 많은 통찰력을 제공합니다 문제.

편집 : 약간 파고 난 후에 질문에 대한 흥미로운 답변을 발견했습니다 .String.Format 대 문자열 연결을 사용하는 것이 더 낫습니까? . 간단히 말해서, +30 표의 답변 작성자는 현지화가 관련되지 않은 경우 문자열 연결에 유리한 주장을합니다.


2
나는 또한 문체 적으로 c에서 printf와 sprintf에 익숙한 사람들과 같은 사람들과 공명한다고 생각합니다.
Jonathan Henson

내 대답을 수정하기 위해 왜 downvote를 알고 싶었을 것입니다. 감사.
Jalayn

4

출력 할 때 문자열이 어떻게 보일지 정확하게 볼 수 있기 때문에 첫 번째 방법을 선호합니다. 공백을 추가하거나 문자열을 추가 할 때 간격을 추가하는 것을 잊어 버리는 것은 매우 쉽습니다.

여분의 문자열을 만들 필요가 없기 때문에 첫 번째 방법에도 성능상의 이점이 있다고 확신합니다. 그러나 그것은 나의 주요 관심사가 아닙니다.


2

첫 번째 옵션을 사용하면 일반적으로 사용되는 형식 문자열을 저장하고 필요한 입력을 줄이고 사용 된 모든 위치에서 문자열을 쉽게 업데이트 할 수 있습니다. 기본적으로 첫 번째 옵션을 사용하면 DRY를 쉽게 구현할 수 있습니다. 언급 한 것처럼 문자열에 여러 변수를 사용해야하는 경우 훨씬 좋은 구문입니다.


아 알다시피, 나는 그 예제를 생각하지 않았다고 생각한다.
Jim

1

나는 string.Format()결과가 정확히 무엇인지 알기가 더 쉽다고 생각 합니다 (따라서 잊어 버린 공백이나 그와 비슷한 문제는 없습니다). 또한 입력하고 수정하기가 더 쉽습니다.

매우 간단한 서식을 지정하려면 +더하기 연산자를 사용하는 것이 더 쉬울 수 있지만 두 문자열을 연결할 때만 사용하는 것이 좋습니다.

방법을 보여 string.Format()에서 진행 : 수정하는 것이 더 쉽습니다, 당신은 당신의 예에서 문장의 끝에 마침표를 추가하고 싶다고 생각 string.Format("The int is {0}", i)하는 것은 string.Format("The int is {0}.", i)단지 하나 개의 문자입니다. 그러나에서가는 "the int is " + i것은 "the int is " + i + '.'훨씬 더.

또 다른 장점은와 string.Format()같이 사용할 형식을 쉽게 지정할 수 있다는 것 string.Format("The int is 0x{0:X}.", i)입니다. 날짜 형식을 지정할 때 더 중요합니다.

효율성에 관해서 string.Format()는 간단한 문자열 연결보다 느릴 것입니다. 그러나 이와 같은 코드는 핫 경로에 있지 않을 가능성이 높으므로 중요하지 않습니다. 그리고 그렇다면을 사용하는 것이 좋습니다 StringBuilder.


string.Format은 내부적으로 StringBuilder를 사용합니다
Bryan Boettcher

1

가장 읽기 쉬운 코드를 사용하십시오. 성능에 대해 걱정하지 마십시오.

아래 예에서는 B가 더 읽기 쉽기 때문에 B를 선호합니다. 그러나 위의 언어 번역도 의미가 있습니다. 누군가가 string.Format을 사용하도록 강요하지 말고 대신 Micro Optimizations Theatre의 슬픈 비극에 관한 Jeff Atwoods의 훌륭한 블로그를 읽고 가리 키십시오 .

ㅏ:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

비:

string output; 
int i = 10;
output = "the int is " + i;

-1

참조 : 문자열 출력 : C # 형식 또는 연결?

이 코드를 고려하십시오.

약간 수정 된 코드 버전입니다.

  1. Console.WriteLine은 내가 측정하려고하는 것보다 약간 느리기 때문에 제거했습니다.
  2. 루프 전에 스톱워치를 쳐다보고 바로 중지합니다.이 방법으로 함수를 실행하는 데 26.4 틱이 걸리더라도 정밀도가 떨어지지 않습니다.
  3. 결과를 반복 횟수로 나누는 방식이 잘못되었습니다. 1000 밀리 초와 100 밀리 초가 있다면 어떻게되는지 확인하십시오. 두 경우 모두 1000000으로 나눈 후 0ms가됩니다.
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

그게 내 결과입니다.

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks

1
이것이 첫 번째 코드 예제 또는 두 번째 코드 예제가 더 나은 디자인인지에 대한 측면에 어떻게 대답합니까? 1M 반복에 대한 0.5 초는 사람이 유지 관리하기 쉬운 코드인지 어떻게 설명합니까?

Jim은 "장단점이 무엇입니까?" 이것은 많은 반복에서 String.Format 이 빠르다 는 것을 보여줍니다 .
jp2code

코드 블록과 OP 코드와의 차이점으로 남기지 않고 답변에 완전히 추가하는 것이 좋습니다. 귀하의 답변은 OP의 질문에 영어로 답변하지 않습니다. 다른 답변을보십시오. 그들로부터 모든 코드를 제거하고 여전히 OP의 질문에 대한 답변을 가질 수 있습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.