it-swarm-ko.tech

인덱스 자리 표시 자 대신 명명 된 입력 매개 변수를 허용 할 수있는 "String.Format"이 있습니까?

이것이 내가 아는 것입니다

str = String.Format("Her name is {0} and she's {1} years old", "Lisa", "10");

하지만 나는 같은 것을 원한다

str = String("Her name is @name and she's @age years old");
str.addParameter(@name, "Lisa");
str.addParameter(@age, 10);
86

C # 6에서는 string interpolation 을 사용할 수 있습니다.

string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";

그의 주석 에서 언급 한 Doug Clutter 와 같이 문자열 보간은 포맷 문자열 도 지원합니다. 콜론 뒤에 형식을 지정하여 형식을 변경할 수 있습니다. 다음 예제는 쉼표와 소수점 2 자리의 숫자를 출력합니다.

var str = $"Your account balance is {balance:N2}"

자신의 답변 에서 언급 한 Bas 와 같이 문자열 보간은 템플릿 문자열을 지원하지 않습니다. 실제로는이를 지원하지 않습니다. 다행히도 훌륭한 도서관에 있습니다.


SmartFormat.NET 예를 들어 명명 된 자리 표시자를 지원합니다.

Smart.Format("{Name} from {Address.City}, {Address.State}", user)

// The user object should at least be like that 

public class User
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string State { get; set; }
}

NuGet 에서 사용할 수 있습니다.


Mustache 또한 훌륭한 솔루션입니다. Bas그의 답변 에서 그 장점을 잘 설명했습니다.

136
Fabien PERRONNET

템플릿 매개 변수를 바꾸는 데 사용하는 데이터가 포함 된 로컬 변수를 할당해도 괜찮은 경우 C # 6.0 문자열 보간 기능 을 사용할 수 있습니다.

기본 원칙은 입력 데이터를 기반으로 상당히 고급 문자열 대체 논리를 수행 할 수 있다는 것입니다.

간단한 예 :

string name = "John";
string message = $"Hello, my name is {name}."

복잡한 예 :

List<string> strings = ...
string summary = $"There are {strings.Count} strings. " 
  + $"The average length is {strings.Select(s => s.Length).Average()}"

단점 :

  • 동적 템플릿을 지원하지 않습니다 (예 : 리소스 파일에서)

(주요) 장점 :

  • 템플릿 교체시 컴파일 시간 검사 를 시행합니다.

구문이 거의 같은 멋진 오픈 소스 솔루션은 Mustache 입니다. 내가 찾은 것 중에서 mustache-sharpNustache 의 두 가지 C # 구현이 있습니다.

나는 mustache-sharp와 함께 일했고 문자열 보간과 같은 힘을 가지고 있지 않지만 가까이 온다는 것을 알았습니다. 예 : github 페이지에서 도난당한 다음 작업을 수행 할 수 있습니다.

Hello, {{Customer.Name}}
{{#newline}}
{{#newline}}
{{#with Order}}
{{#if LineItems}}
Here is a summary of your previous order:
{{#newline}}
{{#newline}}
{{#each LineItems}}
    {{ProductName}}: {{UnitPrice:C}} x {{Quantity}}
    {{#newline}}
{{/each}}
{{#newline}}
Your total was {{Total:C}}.
{{#else}}
You do not have any recent purchases.
{{/if}}
{{/with}}
29
Bas

프로젝트에 C # 6이 없으면 Linq의 .Aggregate ()를 사용할 수 있습니다.

    var str = "Her name is @name and she's @age years old";

    var parameters = new Dictionary<string, object>();
    parameters.Add("@name", "Lisa");
    parameters.Add("@age", 10);

    str = parameters.Aggregate(str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));

질문의 특정 구문과 일치하는 것을 원한다면 Aggregate를 기반으로 매우 간단한 클래스를 만들 수 있습니다.

public class StringFormatter{

    public string Str {get;set;}

    public Dictionary<string, object> Parameters {get;set;}

    public StringFormatter(string p_str){
        Str = p_str;
        Parameters = new Dictionary<string, object>();
    }

    public void Add(string key, object val){
        Parameters.Add(key, val);
    }

    public override string ToString(){
        return Parameters.Aggregate(Str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
    }

}

다음과 같이 사용 가능 :

var str = new StringFormatter("Her name is @name and she's @age years old");
str.Add("@name", "Lisa");
str.Add("@age", 10);

Console.WriteLine(str);

이것은 성능에 대해 이해하기 쉽도록 깔끔한 코드입니다.

25
Chakrava

C # 6에서는 String Interpolation 을 사용하여 변수를 문자열에 직접 추가 할 수 있습니다.

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

string name = "List";
int age = 10;

var str = $"Her name is {name} and she's {age} years old";

문자열 형식 앞에 달러 기호 ($)를 사용하십시오.

18
Steve

그렇다면 왜 교체 만하지 않습니까?

string str = "Her name is @name and she's @age years old";
str = str.Replace("@name", "Lisa");
str = str.Replace("@age", "10");
14
Artem

이 작업을 수행 할 수있는 방법은 없지만,이를위한 클래스를 작성할 수 있습니다.
다음과 같은 일로 시작할 수 있습니다.

public class ParameterizedString
{
    private string _BaseString;
    private Dictionary<string, string> _Parameters;

    public ParameterizedString(string baseString)
    {
        _BaseString = baseString;
        _Parameters = new Dictionary<string, string>();
    }

    public bool AddParameter(string name, string value)
    {
        if(_Parameters.ContainsKey(name))
        {
            return false;
        }
        _Parameters.Add(name, value);
        return true;
    }

    public override string ToString()
    {
        var sb = new StringBuilder(_BaseString);
        foreach (var key in _Parameters.Keys)
        {
            sb.Replace(key, _Parameters[key]);
        }
        return sb.ToString();
    }
}

이 예제는 매개 변수 이름 규칙을 강제하지 않습니다. 즉, 매개 변수 이름을 신중하게 선택해야합니다. 그렇지 않으면 의도하지 않은 문자열 부분이 대체 될 수 있습니다.

7
Zohar Peled

문자열 보간은 좋은 솔루션이지만 C # 6이 필요합니다.

이 경우 StringBuilder

var sb = new StringBuilder();

sb.AppendFormat("Her name is {0} ", "Lisa");
sb.AppendFormat("and she's {0} years old", "10");
// You can add more lines

string result = sb.ToString();
5
ehh

C # 6의 문자열 보간과 함께 표현식을 사용할 수도 있습니다.

string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} year{(age == 1 ? "" : "s")} old";
3
Sean McLarty
    string name = "Lisa";
    int age = 20;
    string str = $"Her name is {name} and she's {age} years old";

이를 Interpolated String 이라고하며, 기본적으로 내부에 표현식이 포함 된 템플릿 문자열입니다.

2
Matt.Mull