[C#] 이름의 목적은 무엇입니까?

버전 6.0에는의 새로운 기능이 nameof있지만 변수 이름 만 사용하고 컴파일시 문자열로 변경하기 때문에 그 목적을 이해할 수 없습니다.

나는 그것을 사용할 때 어떤 목적이있을 것이라고 생각 <T>했지만 그것을 시도 할 때 사용 된 유형 대신 nameof(T)나를 인쇄 T합니다.

목적에 대한 아이디어가 있습니까?



답변

예를 들어 속성 ​​이름을 기준으로 예외를 발생 시키거나 PropertyChanged이벤트를 처리 할 때와 같이 속성 이름을 재사용하려는 경우는 어떻습니까? 재산의 이름을 원할 경우가 많이 있습니다.

이 예제를 보자 :

switch (e.PropertyName)
{
    case nameof(SomeProperty):
    { break; }

    // opposed to
    case "SomeOtherProperty":
    { break; }
}

첫 번째 경우 이름을 바꾸면 SomeProperty속성 이름 도 변경되거나 컴파일이 중단됩니다. 마지막 경우는 그렇지 않습니다.

이는 코드를 컴파일하고 버그가없는 상태로 유지하는 데 매우 유용한 방법입니다.

( Eric Lippert아주 좋은 기사는infoof그것을하지 nameof않았습니까?)


답변

ArgumentException그리고 그 파생물에 정말 유용합니다 .

public string DoSomething(string input)
{
    if(input == null)
    {
        throw new ArgumentNullException(nameof(input));
    }
    ...

이제 누군가 input매개 변수 이름을 리팩터링하면 예외도 최신 상태로 유지됩니다.

또한 속성이나 매개 변수의 이름을 얻기 위해 이전에 리플렉션을 사용해야했던 곳에서도 유용합니다.

귀하의 예 nameof(T)에서 type 매개 변수의 이름을 가져옵니다.이 또한 유용 할 수 있습니다.

throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method.");

또 다른 용도 nameof는 열거 형입니다-일반적으로 사용하는 열거 형의 문자열 이름을 원할 경우 .ToString():

enum MyEnum { ... FooBar = 7 ... }

Console.WriteLine(MyEnum.FooBar.ToString());

> "FooBar"

.Net이 열거 형 값 (예 :)을 보유하고 7런타임에 이름을 찾을 때 실제로는 상대적으로 느립니다 .

대신 다음을 사용하십시오 nameof.

Console.WriteLine(nameof(MyEnum.FooBar))

> "FooBar"

이제 .Net은 컴파일시 열거 이름을 문자열로 바꿉니다.


또 다른 용도는 INotifyPropertyChanged로깅 및 로깅에 사용됩니다. 두 경우 모두 호출하려는 멤버의 이름을 다른 메소드로 전달하려고합니다.

// Property with notify of change
public int Foo
{
    get { return this.foo; }
    set
    {
        this.foo = value;
        PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Foo));
    }
}

또는…

// Write a log, audit or trace for the method called
void DoSomething(... params ...)
{
    Log(nameof(DoSomething), "Message....");
}


답변

nameofC # 6.0의 기능이 유용한 또 다른 사용 사례 -DB 검색이 훨씬 쉬워지는 Dapper 와 같은 라이브러리를 고려하십시오 . 이 라이브러리는 훌륭한 라이브러리이지만 쿼리 내에 속성 / 필드 이름을 하드 코딩해야합니다. 이것이 의미하는 바는 속성 / 필드의 이름을 바꾸려는 경우 새 필드 이름을 사용하도록 쿼리를 업데이트하는 것을 잊을 가능성이 높다는 것입니다. 문자열 보간 및 nameof기능을 사용하면 코드를 유지 관리하고 입력하기가 훨씬 쉬워집니다.

링크에 주어진 예에서

이름없이

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

이름으로

var dog = connection.Query<Dog>($"select {nameof(Dog.Age)} = @Age, {nameof(Dog.Id)} = @Id", new { Age = (int?)null, Id = guid });


답변

귀하의 질문은 이미 목적을 나타냅니다. 이것이 예외를 기록하거나 던지는 데 유용 할 수 있음을 알아야합니다.

예를 들어.

public void DoStuff(object input)
{
    if (input == null)
    {
        throw new ArgumentNullException(nameof(input));
    }
}

이것은 좋은 내가 코드 대신 또는 잘못된 메시지와 함께 예외를 반환 중단 할 변수의 이름을 변경하는 경우 .


물론, 용도는이 간단한 상황에 한정되지 않습니다. nameof변수 또는 속성의 이름을 코딩하는 것이 유용 할 때마다 사용할 수 있습니다 .

다양한 바인딩 및 반사 상황을 고려할 때 용도가 다양합니다. 런타임 오류를 컴파일 타임에 가져 오는 훌륭한 방법입니다.


답변

내가 생각할 수있는 가장 일반적인 유스 케이스는 INotifyPropertyChanged인터페이스로 작업 할 때 입니다. (기본적으로 WPF 및 바인딩과 관련된 모든 것이이 인터페이스를 사용합니다)

이 예제를 살펴보십시오.

public class Model : INotifyPropertyChanged
{
    // From the INotifyPropertyChanged interface
    public event PropertyChangedEventHandler PropertyChanged;

    private string foo;
    public String Foo
    {
        get { return this.foo; }
        set
        {
            this.foo = value;
            // Old code:
            PropertyChanged(this, new PropertyChangedEventArgs("Foo"));

            // New Code:
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));
        }
    }
}

이전 방식에서 볼 수 있듯이 어떤 속성이 변경되었는지 나타내는 문자열을 전달해야합니다. 로 nameof우리가 직접 속성의 이름을 사용할 수 있습니다. 큰 문제는 아닌 것 같습니다. 그러나 누군가 속성 이름을 변경하면 어떤 일이 발생하는지 상상해보십시오 Foo. 문자열을 사용하면 바인딩이 작동하지 않지만 컴파일러는 경고하지 않습니다. nameof를 사용하면 name과 함께 속성 / 인수가 없다는 컴파일러 오류가 발생합니다 Foo.

일부 프레임 워크는 일부 리플렉션 매직을 사용하여 속성의 이름을 얻지 만 이제는 더 이상 필요하지 않은 이름이 있습니다.


답변

가장 일반적인 사용법은 다음과 같은 입력 검증에 있습니다.

//Currently
void Foo(string par) {
   if (par == null) throw new ArgumentNullException("par");
}

//C# 6 nameof
void Foo(string par) {
   if (par == null) throw new ArgumentNullException(nameof(par));
}

첫 번째 경우 par 매개 변수의 이름을 변경하는 메서드를 리팩터링 하면 ArgumentNullException 에서 변경하는 것을 잊어 버릴 수 있습니다 . 로 nameof 당신은 그것에 대해 걱정할 필요가 없습니다.

참조 : nameof (C # 및 Visual Basic 참조)


답변

핵심은 ASP.NET MVC 프로젝트 사용 nameof에서 AccountController.csManageController.csRedirectToAction제어기에 동작을 참조하는 방법.

예:

return RedirectToAction(nameof(HomeController.Index), "Home");

이것은 다음과 같이 번역됩니다.

return RedirectToAction("Index", "Home");

‘Home’컨트롤러에서 ‘Index’작업으로 이동합니다 /Home/Index.