문자열 앞에 $는 무엇을 의미합니까?


251

나는 그대로 문자열을 사용하려고했지만 실수로 $대신 입력 했습니다 @.

그러나 컴파일러는 오류와 컴파일을 제공하지 않았습니다.

그것이 무엇인지 그리고 무엇을 알고 싶어요. 나는 그것을 찾았지만 아무것도 찾을 수 없었다.

그러나 쓸 수 없기 때문에 축약 형 문자열과 다릅니다.

string str = $"text\";

$C #에서 문자열 앞에 무엇을 의미하는지 아는 사람이 있습니까?

string str = $"text";

Visual Studio 2015 CTP를 사용하고 있습니다.

답변:


419

$String.FormatC # 6의 새로운 기능인 문자열 보간법의 약어로 사용됩니다. 귀하의 경우에는 아무것도하지 않는 것처럼 string.Format()아무것도하지 않습니다.

다른 값을 참조하여 문자열을 작성하는 데 사용될 때 자체적으로 제공됩니다. 이전에 다음과 같이 작성해야했습니다 :

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = string.Format("{0},{1},{2}", anInt, aBool, aString);

이제는

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = $"{anInt},{aBool},{aString}";

다른 방법으로 잘 알려지지 않은 다른 형태의 문자열 보간법이 있습니다 $@ (두 심볼의 순서가 중요합니다). @""문자열 의 기능을 혼합 하여 문자열 전체를 $""보지 않고도 문자열 보간을 지원할 \\수 있습니다. 따라서 다음 두 줄 :

var someDir = "a";
Console.WriteLine($@"c:\{someDir}\b\c");

출력합니다 :

c:\a\b\c

29
실제로 String.Format을 사용하지는 않지만 런타임 기반이 아닌 컴파일러 기반 기능입니다.
Shahar Prish 2016 년

2
오늘 배운 점에 유의하십시오.를 사용하면을 (를) 사용 $@하여 "캐릭터 를 탈출해야합니다 "". 이 기능 만 사용하는 경우에는 그렇지 않습니다 $.
Flater

3
@Flater $ 기호와는 아무런 관련이 없습니다. $ 기호가 존재하기 전과 동일한 동작입니다.
BVernon

2
축어 (@) 및 보간 ($) 기호 순서가 중요하다는 점에 대해서는 C # 8에서 수정되어 순서가 더 이상 중요하지 않습니다. 참조 : devsanon.com/uncategorized/…
elkaz

39

보간 된 문자열을 만듭니다. .

에서 MSDN

문자열을 구성하는 데 사용됩니다. 보간 된 문자열 표현식은 표현식이 포함 된 템플릿 문자열처럼 보입니다. 보간 된 문자열 표현식은 포함 된 표현식을 표현식 결과의 ToString 표현으로 대체하여 문자열을 작성합니다.

예 :

 var name = "Sam";
 var msg = $"hello, {name}";

 Console.WriteLine(msg); // hello, Sam

보간 된 문자열 내에서 표현식을 사용할 수 있습니다

 var msg = $"hello, {name.ToLower()}";
 Console.WriteLine(msg); // hello, sam

그것에 대한 좋은 점은 매개 변수의 순서에 대해 걱정할 필요가 없다는 것입니다 String.Format.

  var s = String.Format("{0},{1},{2}...{88}",p0,p1,..,p88);

이제 일부 매개 변수를 제거하려면 모든 카운트를 업데이트해야합니다. 더 이상 그렇지 않습니다.

형식화에string.format 문화 정보를 지정하려는 경우 좋은 예전 은 여전히 ​​관련이 있습니다 .


올바른 문화권 (예 :)을 사용하여 $데이터를 $표현식 내부의 문자열로 변환하면 문화권 정보를 계속 사용 하고 지정할 수 있습니다 {somevar.ToString(...,[Insert culture info here])}.
jrh

18

예제 코드

public class Person {
    public String firstName { get; set; }
    public String lastName { get; set; }
}

// Instantiate Person
var person = new Person { firstName = "Albert", lastName = "Einstein" };

// We can print fullname of the above person as follows
Console.WriteLine("Full-Name - " + person.firstName + " " + person.lastName);
Console.WriteLine("Full-Name - {0} {1}", person.firstName, person.lastName);
Console.WriteLine($"Full-Name - {person.firstName} {person.lastName}");

산출

Full-Name - Albert Einstein
Full-Name - Albert Einstein
Full-Name - Albert Einstein

그것은이다 보간 문자열 . 문자열 리터럴을 사용할 수있는 곳이면 보간 된 문자열을 사용할 수 있습니다. 프로그램을 실행할 때 보간 된 문자열 리터럴을 사용하여 코드를 실행할 때 코드는 보간 식을 평가하여 새 문자열 리터럴을 계산합니다. 이 계산은 보간 된 문자열이있는 코드가 실행될 때마다 발생합니다.

다음 예제는 모든 문자열 보간 값이 계산 된 문자열 값을 생성합니다. 최종 결과이며 유형 문자열이 있습니다. 이중 중괄호 (“{{“ and “}}”)는 모두 단일 중괄호 로 변환됩니다.

string text = "World";
var message = $"Hello, {text}";

위의 두 줄을 실행 한 후 변수 message에는 "Hello, World"가 포함됩니다.

Console.WriteLine(message); // Prints Hello, World

참조 -MSDN


10

멋진 기능. 나는 이것이 왜 사람들에게 명백하지 않은 경우 이것이 string.format보다 나은지 강조하고 싶습니다.

매개 변수와 일치시키기 위해 order string.format을 "{0} {1} {2}"(으)로 말하는 사람을 읽었습니다. string.format에서 "{0} {1} {2}"을 (를) 주문하지 않아도됩니다. "{2} {0} {1}"을 (를) 수행 할 수도 있습니다. 그러나 20과 같은 매개 변수가 많은 경우 문자열을 "{0} {1} {2} ... {19}"로 시퀀싱하려고합니다. 뒤섞인 엉망이라면 매개 변수를 정렬하는 데 어려움을 겪을 것입니다.

$를 사용하면 매개 변수를 세지 않고 인라인으로 매개 변수를 추가 할 수 있습니다. 이를 통해 코드를 훨씬 쉽게 읽고 관리 할 수 ​​있습니다.

$의 단점은 문자열에서 매개 변수를 쉽게 반복 할 수 없으므로 입력해야한다는 것입니다. 예를 들어 System.Environment.NewLine을 입력하는 데 지치면 string.format ( "... {0} ... {0} ... {0}", System.Environment.NewLine), 그러나 $로, 당신은 그것을 반복해야합니다. $ "{0}"은 (는) "0"을 반환하므로 $ "{0}"을 (를) 수행하고이를 string.format에 전달할 수 없습니다.

부수적으로, 나는 또 다른 중복 된 tpoic에서 주석을 읽었습니다. 나는 언급 할 수 없으므로 여기 있습니다. 그는 말했다

string msg = n + " sheep, " + m + " chickens";

둘 이상의 문자열 객체를 만듭니다. 이것은 사실이 아닙니다. 이 작업을 한 줄로 수행하면 하나의 문자열 만 만들어 문자열 캐시에 배치됩니다.

1) string + string + string + string;
2) string.format()
3) stringBuilder.ToString()
4) $""

모두 문자열을 반환하고 캐시에 하나의 값만 만듭니다.

반면에 :

string+= string2;
string+= string2;
string+= string2;
string+= string2;

4 ";"가 있으므로 캐시에 4 개의 다른 값을 작성합니다.

따라서 다음과 같은 코드를 작성하는 것이 더 쉬울 것이지만 Carlos Muñoz가 수정 한대로 5 개의 보간 문자열을 작성합니다.

string msg = $"Hello this is {myName}, " +
  $"My phone number {myPhone}, " +
  $"My email {myEmail}, " +
  $"My address {myAddress}, and " +
  $"My preference {myPreference}.";

이렇게하면 코드를 매우 쉽게 읽을 수있는 동안 캐시에 단일 문자열이 생성됩니다. 성능에 대해서는 확실하지 않지만 MS가 아직 수행하지 않은 경우이를 최적화 할 것이라고 확신합니다.


1
마지막 예제가 잘못되었습니다. 실제로 두 개의 문자열을 보간합니다. 하나는 보간 된 문자열과 다른 하나는 나머지 문자열입니다. {myName}을 가진 것만 보간되고 다른 것들은 예상대로 작동하지 않습니다.
Carlos Muñoz

1
그리고 5 개의 문자열 앞에 $를 붙이면 각각 고유 한 5 개의 보간 된 문자열을 만든 String.Format()다음 런타임에로 연결됩니다 String.Concat. 따라서 여러 줄로 나누지 않는 것이 좋습니다.
Carlos Muñoz

1
당신은 맞습니다 @Carlos Muñoz, 나는 그것을 고쳤다. 실수를 잡아 주셔서 감사합니다.
BoBoDev

8

두 가지를 결합 할 수도 있습니다 (약간 이상해 보이지만).

// simple interpolated verbatim string
WriteLine($@"Path ""C:\Windows\{file}"" not found.");

5
입력 한 순서를 결정할 수있는 경우 $@또는 @$. 불행히도 그것은 단지$@
Bauss

2
@Bauss 이것은 의미가 있습니다. @문자열 리터럴을 나타내는 방법을 정의합니다. $에 대한 바로 가기입니다 string.Format. 이라고 생각$(@"");
marsze

에 대한 바로 가기가 아닙니다 string.Format. 로 파싱되는 값을 제시하는 것은 설탕 string.Format이므로 부분적으로 의미가 있지만 완전히는 아닙니다.
Bauss

3
필자 $는 기본적으로 묵시적 함수 호출이라고 말하지만 10 진수 리터럴 @과 마찬가지로 리터럴의 일부입니다 m. 따라서 논리적 순서가 하나 밖에없는 이유입니다.
marsze

2
나는 이것이 대부분 시연 $하기 위해 여기에 있었지만 디렉토리 분리기가 '/'또는 '\'인지 여부를 하드 코딩하지 않고 최대 호환성을 위해 이중 슬래시 또는 슬래시가 누락되는 피할 수없는 스크류 업을 피합니다. Path.Combine()디렉토리와 파일로 작업 할 때 문자열 연결을 사용 하는 대신 사용 하는 것이 좋습니다 .
jrh

6

string.Format보다 편리하며 여기에서도 인텔리전스를 사용할 수 있습니다.

여기에 이미지 설명을 입력하십시오

그리고 여기 내 테스트 방법이 있습니다 :

[TestMethod]
public void StringMethodsTest_DollarSign()
{
    string name = "Forrest";
    string surname = "Gump";
    int year = 3; 
    string sDollarSign = $"My name is {name} {surname} and once I run more than {year} years."; 
    string expectedResult = "My name is Forrest Gump and once I run more than 3 years."; 
    Assert.AreEqual(expectedResult, sDollarSign);
}

6

문자열 보간을 나타냅니다.

문자열 평가에 컴파일 시간 보호 기능을 추가하기 때문에 사용자를 보호합니다.

더 이상 예외가 발생하지 않습니다. string.Format("{0}{1}",secondParamIsMissing)


6

다음 예는 보간 문자열을 사용하여 string.Format()청결과 가독성에 관한 다양한 장점을 강조 합니다. 또한 호출되는 {}것과 마찬가지로 다른 함수 인수와 마찬가지로 코드 내의 코드 가 평가됨을 보여줍니다 string.Format().

using System;

public class Example
{
   public static void Main()
   {
      var name = "Horace";
      var age = 34;
      // replaces {name} with the value of name, "Horace"
      var s1 = $"He asked, \"Is your name {name}?\", but didn't wait for a reply.";
      Console.WriteLine(s1);

      // as age is an integer, we can use ":D3" to denote that
      // it should have leading zeroes and be 3 characters long
      // see https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-pad-a-number-with-leading-zeros
      //
      // (age == 1 ? "" : "s") uses the ternary operator to 
      // decide the value used in the placeholder, the same 
      // as if it had been placed as an argument of string.Format
      //
      // finally, it shows that you can actually have quoted strings within strings
      // e.g. $"outer { "inner" } string"
      var s2 = $"{name} is {age:D3} year{(age == 1 ? "" : "s")} old.";
      Console.WriteLine(s2); 
   }
}
// The example displays the following output:
//       He asked, "Is your name Horace?", but didn't wait for a reply.
//       Horace is 034 years old.

6

$ 구문은 좋지만 단점이 있습니다.

문자열 템플릿과 같은 것이 필요한 경우 클래스 수준에서 필드로 선언됩니다.

그런 다음 동일한 수준에서 변수를 선언해야합니다 ... 실제로는 시원하지 않습니다.

문자열을 사용하는 것이 훨씬 좋습니다.

class Example1_StringFormat {
 string template = $"{0} - {1}";

 public string FormatExample1() {
   string some1 = "someone";
   return string.Format(template, some1, "inplacesomethingelse");
 }

 public string FormatExample2() {
   string some2 = "someoneelse";
   string thing2 = "somethingelse";
   return string.Format(template, some2, thing2);
 }
}

글로벌 사용은 실제로 좋지 않으며 그 외에는 글로벌에서도 작동하지 않습니다.

 static class Example2_Format {
 //must have declaration in same scope
 static string some = "";
 static string thing = "";
 static string template = $"{some} - {thing}";

//This returns " - " and not "someone - something" as you would maybe 
//expect
 public static string FormatExample1() {
   some = "someone";
   thing = "something";
   return template;
 }

//This returns " - " and not "someoneelse- somethingelse" as you would 
//maybe expect
 public static string FormatExample2() {
   some = "someoneelse";
   thing = "somethingelse";
   return template;
 }
}

이 답변은 $ string을 선언 할 때가 아니라 $ string을 "호출"할 때 보간이 발생한다는 것을 나타내므로 중요합니다.
dx_over_dt

1
클래스 범위에서 보간 변수를 선언하는 안티 패턴에 대해서는 맞습니다. 그러나 해당 변수가 이미 클래스 속성에 속하는 경우이 패턴이 효과적입니다.
dx_over_dt

@dx_over_dt 잘못되었습니다. 보간 된 문자열은 선언 될 때 평가됩니다. 이것이 샘플 코드가 의미가없는 이유입니다. 또한 컴파일되지 않습니다.
NineBerry

@NineBerry 보간 된 문자열이 선언 될 때 평가되고 Example_ $ Format이 컴파일되지 않고 샘플 코드가 이해가되지 않는 것에 대해 모두 맞습니다. :) 샘플을 수정하여 더 잘 설명했습니다.
Tom

5

작동 방식을 모르겠지만 값을 탭하는 데 사용할 수도 있습니다!

예 :

Console.WriteLine($"I can tab like {"this !", 5}.");

물론 "this!"를 대체 할 수 있습니다. 탭을 변경할 수있는 것처럼 변수 나 의미있는 것을 사용하십시오.


예 당신은 또한 문자열의 서식을 지정할 수 있습니다 msdn.microsoft.com/en-us/library/dn961160.aspx
M.kazem Akhgary

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.