선택적 매개 변수의 기본값으로 String.Empty를 사용할 수 없습니다.


89

Bill Wagner의 Effective C # 을 읽고 있습니다. 에서 항목 14 - 중복 초기화 로직을 최소화 , 그는 새로운 선택적 매개 변수는 생성자에서 기능을 사용하여 다음과 같은 예를 보여줍니다

public MyClass(int initialCount = 0, string name = "")

그가 사용하는 것을 알 수 ""대신 string.Empty.
그는 다음과 같이 말합니다.

[위의 예에서] 두 번째 생성자가 name 매개 변수 의 기본값으로 더 관례적인 string.Empty. 이는 string.Empty컴파일 시간 상수가 아니기 때문 입니다. 문자열 클래스에 정의 된 정적 속성입니다. 컴파일 상수가 아니기 때문에 매개 변수의 기본값으로 사용할 수 없습니다.

string.Empty모든 상황 에서 정적을 사용할 수 없다면 , 그것이 그 목적을 무너 뜨리지 않습니까? 나는 우리가 빈 문자열을 참조하는 시스템 독립적 인 수단을 가지고 있는지 확인하기 위해 그것을 사용할 것이라고 생각했습니다. 내 이해가 잘못 되었습니까? 감사.

업데이트
후속 댓글입니다. MSDN에 따르면 :

각 선택적 매개 변수에는 정의의 일부로 기본값이 있습니다. 해당 매개 변수에 대해 인수가 전송되지 않으면 기본값이 사용됩니다. 기본값은 상수 여야합니다.

그러면 우리는 System.Environment.NewLine둘 중 하나 를 사용할 수 없거나 새로 인스턴스화 된 객체를 기본값으로 사용할 수 없습니다 . 아직 VS2010을 사용하지 않았는데 이것은 실망 스럽습니다!


2
나는 빈 문자열이 다른 플랫폼에서 어떻게 표현되는지의 차이점을 알지 못합니다. 개행과는 다릅니다.
Tom Cabanski

맞아요, 저는 그렇게 생각하고 있었는데 코드에서 더보기 좋게 보이나요?
Mikeyg36

1
'시스템'이 아닌 CLR이 ""가 빈 문자열인지 여부를 결정하는 요소입니다. 따라서 ""가 호환 CLR 구현에서 문자열을 참조하는 시스템 독립적 인 방법이라고 안전하게 가정 할 수 있다고 생각합니다.
Chris Taylor

"시스템 독립적"? 어, 시스템 특정 ""와는 반대로? (???)
Qwertie

MSDN에 따르면 :이 필드의 값은 길이가 0 인 문자열 ""입니다. 그래서 많은 사람들이 지적하는 것처럼 분명히 플랫폼 독립성과 관련이 없습니다. 그러나 사람들은 그것이 왜 사용되어야하는지 정말로 모르는 것 같습니다!
Mikeyg36

답변:


66

C # 2.0 컴파일러에서는 String.Empty어쨌든 요점이 거의 없으며 실제로 컴파일러가 일부 참조를 인라인 ""할 수 있지만 .NET 과 동일한 작업을 수행 할 수 없기 때문에 실제로는 비관적 입니다 String.Empty.

C # 1.1에서는 빈 문자열을 모두 포함하는 많은 독립 개체를 만드는 것을 피하는 것이 유용했지만 그 시절은 사라졌습니다. ""잘 작동합니다.


7
.NET 1.1에서도 "많은"독립 개체를 만들지 않습니다. 이 점에서 1.1과 2.0의 차이점에 대한 세부 사항을 기억할 수는 없지만 문자열 리터럴 인턴이 2.0에서만 도입 된 것과는 다릅니다.
Jon Skeet

설명해 주셔서 감사합니다. 나는 둘러 보았지만 C # 2.0의 변경 사항에 대한 좋은 요약을 찾지 못했지만 이전에 읽었을 것입니다. 더 많은 기술 정보에 대한 링크가 포함 된 2008 년의 StackOverflow 답변을 찾았습니다. stackoverflow.com/questions/151472/…
Andy Mortimer

1
끈이별로 없다는 말은 싫지만 고개를 끄덕 이겠습니다. 나는 그것이 내 개인적인 의견이지만 깨끗해 보인다는 것을 알았다. 많은 장소 string.Empty는 사용할 수 없으며,이 경우 ""를 사용하는 데 문제가 없습니다.
xximjasonxx

15
String.Empty를 사용하여 빈 문자열을 신속하게 식별하는 것이 ""를 두 번보고 아포스트로피 나 그 안에 숨겨진 것과 같은 것이 없는지 확인하는 것보다 훨씬 쉽다는 것을 알았습니다. 그래도 설명에 +1.
NotMe

11
+1 크리스. 또한 VS에서는 ""사용에 대한 검색을 수행 할 수 없습니다 (주석 및 마크 업을 포함하여 모든 텍스트 일치를 다시 가져 오는 표준 찾기를 수행하는 것 외에는). string.Empty를 사용하여 코드 별 용도를 검색 할 수 있습니다.
MutantNinjaCodeMonkey

53

선택적 매개 변수 값으로 실제로 사용하려는 경우 빈 문자열에 대한 자체 상수를 정의하는 것을 막을 수는 없습니다.

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[선호하도록 여담 이유로서 String.Empty위에 ""다른 답변에서 언급되지 않은, 일반적으로, 육안으로 보이지 않는 다양한 효과적으로 유니 코드 문자 (제로 참가자 폭 등)이 있다는 것이다. 따라서 보이는 ""것이 반드시 빈 문자열은 아니지만 String.Empty사용중인 것을 정확히 알고 있습니다. 이것이 버그의 일반적인 원인이 아니라는 것을 알고 있지만 가능합니다.]


2
보이지 않는 식별자 문자도 있으므로 String_Empty처럼 보이는 것이 반드시 그런 것은 아닙니다. 유니 코드 표준은 보안 고려 사항에 대해 거의 무시 된 장을 가지고 있습니다.
Jim Balter 2015 년

25

원래 질문에서 :

나는 우리가 빈 문자열을 참조하는 시스템 독립적 인 수단을 가지고 있는지 확인하기 위해 그것을 사용할 것이라고 생각했습니다.

어떤 방식으로 빈 문자열이 시스템마다 다를 수 있습니까? 항상 문자가없는 문자열입니다! false를 반환 하는 구현을 발견하면 정말 두려울 것입니다. string.Empty == "":) 이것은 같은 것과 같지 않습니다Environment.NewLine .

Counter Terrorist의 현상금 게시물에서 :

다음 C # 릴리스에서 String.Empty를 기본 매개 변수로 사용할 수 있기를 바랍니다. :디

글쎄 그것은 확실히 일어나지 않을 것입니다.

개인적으로 매우 다른 기본값 설정 메커니즘을 좋아했지만, 선택적 매개 변수가 작동하는 방식은 시작부터 .NET에있었습니다. 항상 메타 데이터에 상수를 포함하여 호출 코드가 해당 상수를 호출에 복사 할 수 있도록합니다. 해당 인수가 제공되지 않은 경우 사이트.

함께 string.Empty그건 정말 무의미 - 사용하여 ""당신이 원하는 것을 할 것입니다; 문자열 리터럴을 사용하는 것이 그렇게 고통 스럽습니까? (나는 모든 곳에서 리터럴을 사용합니다. 절대 사용하지 않습니다. string.Empty하지만 그것은 다른 주장입니다.)

그것이이 질문에 대해 저를 놀라게하는 것입니다. 불만은 실제로 실제 문제를 일으키지 않는 무언가를 중심으로 이루어집니다 . 실제로 다를 수 있기 때문에 실행 시간에 기본값을 계산하려는 경우 더 중요합니다. 예를 들어, DateTime매개 변수가 있는 메소드를 호출하고 기본값을 "현재 시간"으로 설정 하려는 경우를 상상할 수 있습니다 . 현재 내가 아는 모호하고 우아한 해결 방법은 다음과 같습니다.

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

...하지만 항상 적절한 것은 아닙니다.

결론적으로:

  • 나는 이것이 C #의 일부가 될 것이라고 매우 의심합니다.
  • 대한 string.Empty그것의 무의미 어쨌든
  • 항상 같은 값을 가지지 않는 다른 값의 경우 정말 고통 스러울 있습니다.

이것은 실제로 문제를 해결하는 좋은 방법입니다. Environment.Newline.. 같은 다른 장치 종속 변수를 전달 / 설정하는 데 동일한 방법을 사용할 수 있습니다 . 예제에서 누락 된 유일한 것은 변수에서 null을 확인하고 개발자에게 nullable이기는하지만 예외를 반환하는 예외를 던지는 것입니다. 허용되지 않음. if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");}또는 그런 것. 하지만 나는 이것을 정말로 좋아한다! 당신의 방식대로하는 것에 대한 다른주의 사항이 있습니까?
MaxOvrdrv 2014 년

@MaxOvrdrv : null이 오류가되는 것을 원하지 않습니다. 요점은 null 일 때 기본값을 계산한다는 것입니다. 주의 할 점은 null 자체가 유효한 값으로 전달되는 것을 허용하지 않는다는 것입니다.
Jon Skeet 2014 년

당신은 그것에 대해 완전히 옳습니다. 내 잘못이야. -그리고 네, 그것이 유일한 진짜 경고 일 것입니다. 그렇게 나쁘지 않습니다. 다시 말하지만,이 솔루션이 정말 마음에 듭니다! :) 게시 해 주셔서 감사합니다! :)
MaxOvrdrv 2014 년

7

나는 문자열을 사용하지 않습니다. 빈, 나는 그것의 요점을 볼 수 없습니다. 프로그래밍을 처음 접하는 사람들이 더 쉽게 사용할 수 있을지 모르지만, 그것조차도 유용 할 것 같지 않습니다.


2
아마 혼란을 방지 ""하고 " ",하지만 난 그 말을 할 수없는 " "모든 것을 일반적이다.
Greg

8
그 차이를 구분할 수없는 사람은 더 나은 안경이 필요하거나 화면 해상도를 낮추는 것이 좋습니다. 시력이 나빠서 그 실수를 한 번도 기억할 수 없습니다 (그리고이 두 가지를 모두 포함하는 많은 코드로 작업해야합니다).
Hans Olsson

2
string.Empty는 프로그래머의 정확한 의도를 찾는 데 유용합니다. ""는 의도에 대해 아무 말도하지 않습니다. 프로그래머의 의도가이 "웃음"과 같은 변수를 초기화하려고했지만 잊어 버린 경우 ...이 경우 무한한 가능성과 문자열이 있습니다
.Empty

4

나는 string.Empty의 아이디어는 가독성을 향상시키는 것입니다. 다른 플랫폼에서 표현되는 방식에 차이가있는 개행 문자와는 다릅니다. 기본 매개 변수에서는 사용할 수 없습니다. 그러나 Windows와 Linux의 Mono와 같은 것 사이에 이식하면 문제가 발생하지 않습니다.


5
어떤 사람들은 String.Empty더 읽기 쉽다고 생각한다는 점이 당신이 옳다고 생각합니다 . . . 개인적으로는 약간 열매가 많은 것 같아요. ""아마도 가장 일반적인 문자열 일 것이고 모든 사람들이 그것을 수십억 번 본 적이 있는데 어떻게 읽을 수 없습니까? String.Empty마치 Int32.Zero.
Tim Goodman

3

참고로 속성 생성자에 전달 된 값에 동일한 제약 조건이 적용되는 것처럼 보입니다.이 값은 상수 여야합니다. string.empty는 다음과 같이 정의됩니다.

public static readonly string Empty

실제 상수가 아니라 사용할 수 없습니다.


2

나는 string.Empty순전히 가독성을 위해 사용 합니다.

다른 사람이 나중에 내 코드를 읽고 변경해야하는 경우에는 내가 무언가를 확인하거나 빈 문자열로 설정해야한다는 것을 알고 있습니다. just ""을 사용하면 내가 원하는 문자열을 넣는 것을 잊었을 수 있기 때문에 때때로 버그와 혼란을 일으킬 수 있습니다.

예를 들면 :

if(someString == string.Empty)
{

}

vs

if(someString == "")
{

}

첫 번째 if진술은 나에게 훨씬 더 신중하고 읽기 쉬운 것처럼 보입니다. 그러나 이것은 단지 선호 사항이기 때문에 . ""대신 을 사용해야 한다는 기차 스매시가 실제로 보이지 않습니다 string.Empty.


-2

아마도이 문제에 대한 최선의 해결책은 다음과 같은 방식으로이 메서드의 오버로드 일 것입니다.

public static void PrintString() 
{ 
    PrintString(string.Empty);
}

3
위의 질문에 대한 답은 무엇입니까?
PRANAV 싱

1
선택적 매개 변수의 기본값에 대해 어떻게 도움이됩니까?
기본 로케일
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.