이름의 목적은 무엇입니까?
버전 6.0에는 다음과 같은 새로운 기능이 있습니다.nameof하지만 저는 그것의 목적을 이해할 수 없습니다. 왜냐하면 그것은 단지 변수 이름을 가지고 컴파일할 때 문자열로 바꾸기 때문입니다.
저는 사용할 때 어떤 목적이 있을 거라고 생각했습니다.<T>하지만 내가 하려고 할 때.nameof(T)그것은 단지 나를 프린트합니다.T사용된 유형 대신.
목적에 대해 생각나는 것이 있습니까?
를 들어 이름에 를 던지거나 이름을 할 때?PropertyChanged이벤트. 숙박업소의 이름을 알고 싶은 경우가 많습니다.
다음 예를 들어 보겠습니다.
switch (e.PropertyName)
{
case nameof(SomeProperty):
{ break; }
// opposed to
case "SomeOtherProperty":
{ break; }
}
번째 이름을 첫번경우, 이바꾸기로 합니다.SomeProperty속성 정의와 속성 정의를 모두 변경하지 않으면 컴파일 오류가 발생합니다.nameof(SomeProperty)표현. 두 두번경우, 바기꾸이로 합니다.SomeOtherProperty하는 것."SomeOtherProperty"되고 빌드 가 발생하지 . string을 실행하면 오류가 발생하지 않습니다.
이것은 코드 컴파일 및 버그가 없는 상태를 유지하는 데 매우 유용한 방법입니다.
(에릭 리퍼트의 아주 좋은 기사는 왜.infoof성공하지 못했지만, 반면에.nameof했습니다)
에 정말 유용합니다.ArgumentException 그은 다음과 .
public string DoSomething(string input)
{
if(input == null)
{
throw new ArgumentNullException(nameof(input));
}
...
만약 누군가가 그 이름을 리팩터링한다면,input매개 변수 예외도 최신 상태로 유지됩니다.
또한 속성 또는 매개 변수의 이름을 얻기 위해 이전에 반사를 사용해야 했던 일부 위치에서도 유용합니다.
를 들어 를들어예에서,nameof(T)형식 매개 변수의 이름을 가져옵니다. 이것도 유용할 수 있습니다.
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....");
}
C# 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문자열을 사용하면 바인딩이 작동하지 않지만 컴파일러는 경고를 표시하지 않습니다.을 사용하면 이 " 을인용이이름성사때속할에다없수/가다발니오생합류가컴파일는러름인"인 속성합니다.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에서 변경하는 것을 잊게 될 수 있습니다.당신의 이름으로 그것에 대해 걱정할 필요가 없습니다.
참고 항목: (C# 및 Visual Basic Reference)의 이름
Core 는 ASP.NET Core MVC를 사용합니다.nameof와 함께RedirectToAction컨트롤러의 작업을 참조하는 방법입니다.
예:
return RedirectToAction(nameof(HomeController.Index), "Home");
이는 다음을 의미합니다.
return RedirectToAction("Index", "Home");
사용자를 의 '/Home/Index.
코드에 변수 이름을 인쇄해야 한다고 가정해 보겠습니다.다음을 작성하는 경우:
int myVar = 10;
print("myVar" + " value is " + myVar.toString());
를 리팩터링해서 으로 그고만누코가드리를팩하다고사면이용다한름을른링터리군약가▁for▁someone▁and▁name▁another▁and면▁ref▁then다▁if사용한▁uses▁code이름orsact▁the.myVar그/그녀는 당신의 코드에서 문자열 값을 찾고 그에 따라 그것을 변경해야 할 것입니다.
대신 다음과 같이 쓰면 됩니다.
print(nameof(myVar) + " value is " + myVar.toString());
자동으로 리팩터링하는 것이 도움이 될 것입니다!
MSDN 기사에는 여러 가지 중에서 MVC 라우팅(나에게 정말로 개념을 클릭한 예)이 나열되어 있습니다.(형식이 지정된) 설명 단락은 다음과 같습니다.
- 코드에서 오류를 보고할 때,
- 모델-뷰-컨트롤러(MVC) 링크 후킹,
- 화재 속성 변경 이벤트 등
메소드의 문자열 이름을 캡처하려는 경우가 많습니다.이름을 사용하면 정의 이름을 바꿀 때 코드를 유효하게 유지하는 데 도움이 됩니다.
이전에는 문자열 리터럴을 사용하여 정의를 참조해야 했습니다. 이는 도구가 문자열 리터럴을 확인할 수 없기 때문에 코드 요소의 이름을 바꿀 때 취약합니다.
승인된/최상위 답변은 이미 몇 가지 우수한 구체적인 예를 제공합니다.
했듯이, 다른사람이지이듯했적미이들,이듯,nameof연산자는 요소에 지정된 이름을 소스 코드에 삽입합니다.
이 끈 리팩터링이 안전하기 때문에 리팩터링 측면에서 정말 좋은 아이디어라고 덧붙이고 싶습니다.이전에는 같은 목적으로 반사를 이용하는 정적 방법을 사용했지만 런타임 성능에 영향을 미칩니다. 그nameof연산자는 런타임 성능에 영향을 미치지 않으며 컴파일 시간에 작업을 수행합니다.,를 보시면,MSIL코드 당신은 포함된 문자열을 발견할 것입니다.다음 방법 및 분해된 코드를 참조하십시오.
static void Main(string[] args)
{
Console.WriteLine(nameof(args));
Console.WriteLine("regular text");
}
// striped nops from the listing
IL_0001 ldstr args
IL_0006 call System.Void System.Console::WriteLine(System.String)
IL_000C ldstr regular text
IL_0011 call System.Void System.Console::WriteLine(System.String)
IL_0017 ret
그러나 소프트웨어를 난독화하려는 경우에는 단점이 될 수 있습니다.난독화 후에는 포함된 문자열이 더 이상 요소의 이름과 일치하지 않을 수 있습니다.이 텍스트에 의존하는 메커니즘은 깨질 것입니다.다음을 포함하지만 이에 국한되지 않는 예는 다음과 같습니다.속성 변경됨...
런타임 중에 이름을 결정하면 성능이 다소 떨어지지만 난독화에 안전합니다.난독화가 필요하지 않거나 계획되지 않은 경우에는nameof교환입니다.
의 은?nameof연산자는 아티팩트의 소스 이름을 제공합니다.
일반적으로 소스 이름은 메타데이터 이름과 같습니다.
public void M(string p)
{
if (p == null)
{
throw new ArgumentNullException(nameof(p));
}
...
}
public int P
{
get
{
return p;
}
set
{
p = value;
NotifyPropertyChanged(nameof(P));
}
}
그러나 항상 그렇지는 않을 수 있습니다.
using i = System.Int32;
...
Console.WriteLine(nameof(i)); // prints "i"
또는:
public static string Extension<T>(this T t)
{
return nameof(T); returns "T"
}
리소스 이름을 지정하는 데 한 가지 용도를 사용했습니다.
[Display(
ResourceType = typeof(Resources),
Name = nameof(Resources.Title_Name),
ShortName = nameof(Resources.Title_ShortName),
Description = nameof(Resources.Title_Description),
Prompt = nameof(Resources.Title_Prompt))]
이 경우 리소스에 액세스하는 데 생성된 속성이 필요하지 않았지만 이제 리소스가 존재하는지 컴파일 시간을 확인할 수 있습니다.
이름의 목적은 리팩터링입니다.예를 들어 코드의 다른 위치에 있는 이름을 통해 참조하는 클래스의 이름을 변경하면 원하는 컴파일 오류가 발생합니다.이름을 사용하지 않고 일반 문자열만 참조로 사용한 경우 클래스 이름을 변경하려면 전체 텍스트 검색을 수행해야 합니다.그것은 정말 골치 아픈 일입니다.귀하의 이름을 사용하면 IDE에서 모든 변경 사항을 자동으로 확인하고 구축할 수 있습니다.
사용사의 다른 nameof색인을 확인하는 대신 탭 페이지를 확인할 수 있습니다.Name다음과 .
if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
// Do something
}
덜 지저분함 :)
는 그것을 합니다.nameof응용 프로그램에서 매우 길고 복잡한 SQL 문의 가독성을 높입니다.이렇게 하면 변수가 일련의 문자열에서 두드러지고 SQL 문에서 변수가 사용되는 위치를 파악하는 작업이 필요하지 않습니다.
public bool IsFooAFoo(string foo, string bar)
{
var aVeryLongAndComplexQuery = $@"SELECT yada, yada
-- long query in here
WHERE fooColumn = @{nameof(foo)}
AND barColumn = @{nameof(bar)}
-- long query here";
SqlParameter[] parameters = {
new SqlParameter(nameof(foo), SqlDBType.VarChar, 10){ Value = foo },
new SqlParameter(nameof(bar), SqlDBType.VarChar, 10){ Value = bar },
}
}
도 하중나의 중 nameof키워드는 설정을 위한 것입니다.Binding프로그래밍 방식으로 wpf.
설정하는Binding은 야합해니다설을 설정해야 .Path 타래로와 함께nameof키워드, Refactor 옵션을 사용할 수 있습니다.
를 들어,이 있으면 신이만약.IsEnable의종속의 UserControl그리고 당신은 그것을 묶고 싶어합니다.IsEnableCheckBox의 신의에UserControl다음 두 코드를 사용할 수 있습니다.
CheckBox chk = new CheckBox();
Binding bnd = new Binding ("IsEnable") { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);
그리고.
CheckBox chk = new CheckBox();
Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);
첫 번째 코드는 리팩터링할 수 없지만 두 번째 코드는...
이전에는 다음과 같은 방법을 사용했습니다.
// Some form.
SetFieldReadOnly( () => Entity.UserName );
...
// Base form.
private void SetFieldReadOnly(Expression<Func<object>> property)
{
var propName = GetPropNameFromExpr(property);
SetFieldsReadOnly(propName);
}
private void SetFieldReadOnly(string propertyName)
{
...
}
이유 - 시간 안전을 컴파일합니다.아무도 조용히 속성 이름을 변경하고 코드 로직을 해제할 수 없습니다.이제 ()의 이름을 사용할 수 있습니다.
ASP.Net MVC를 사용할 때 이점이 있습니다.HTML 도우미를 사용하여 뷰에서 일부 컨트롤을 작성할 때 HTML 입력의 이름 속성에 속성 이름을 사용합니다.
@Html.TextBoxFor(m => m.CanBeRenamed)
이는 다음과 같은 것을 만듭니다.
<input type="text" name="CanBeRenamed" />
이제 Validate 메서드에서 속성을 검증해야 하는 경우 다음 작업을 수행할 수 있습니다.
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (IsNotValid(CanBeRenamed)) {
yield return new ValidationResult(
$"Property {nameof(CanBeRenamed)} is not valid",
new [] { $"{nameof(CanBeRenamed)}" })
}
}
리팩토링 도구를 사용하여 속성 이름을 변경하는 경우 유효성 검사가 중단되지 않습니다.
언급URL : https://stackoverflow.com/questions/31695900/what-is-the-purpose-of-nameof
'programing' 카테고리의 다른 글
| 구문 오류:예기치 않은 토큰 가져오기 TypeORM 엔티티 (0) | 2023.06.18 |
|---|---|
| 값 순서를 변경하지 않고 요인 수준 재정렬 (0) | 2023.06.13 |
| 전체 구성 요소를 사용자에게 설치하지 않고 ODAC를 사용하는 .NET 응용 프로그램을 배포하려면 어떻게 해야 합니까? (0) | 2023.06.13 |
| 로그아웃할 때 블랙리스트에 대한 400건의 잘못된 요청을 받았습니다. (0) | 2023.06.13 |
| VBA 코드에서 Excel 셀의 #N/A를 확인하는 중 (0) | 2023.06.13 |