6.0版获得了nameof的新功能,但我不能理解它的目的,因为它只是接受变量名并在编译时将其更改为字符串。

我认为它在使用<T>时可能有一些目的,但当我尝试命名(T)时,它只是打印我一个T而不是使用的类型。

知道目的吗?


当前回答

操作符名称的目的是提供工件的源名称。

通常源名称与元数据名称相同:

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"

Or:

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))]

事实上,在这种情况下,我甚至不需要生成的属性来访问资源,但是现在我有一个编译时检查资源是否存在。

其他回答

操作符名称的目的是提供工件的源名称。

通常源名称与元数据名称相同:

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"

Or:

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))]

事实上,在这种情况下,我甚至不需要生成的属性来访问资源,但是现在我有一个编译时检查资源是否存在。

我发现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 },
    }
}

它在使用ASP时具有一定的优势。净MVC。当你使用HTML helper在视图中构建一些控件时,它使用HTML输入的name属性中的属性名:

@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)}" })
  }
}

如果你使用重构工具重命名你的属性,你的验证不会被破坏。

ASP。NET核心MVC项目使用AccountController.cs和ManageController.cs中的name和RedirectToAction方法来引用控制器中的动作。

例子:

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

这句话的意思是:

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

和takes将用户带到'Home'控制器中的'Index'动作,即/Home/Index。

nameof关键字的用法之一是在wpf中以编程方式设置Binding。

要设置绑定,你必须设置路径字符串和nameof关键字,可以使用重构选项。

例如,如果你在你的UserControl中有IsEnable依赖属性,你想把它绑定到你的UserControl中某些复选框的IsEnable上,你可以使用这两个代码:

CheckBox chk = new CheckBox();
Binding bnd = new Binding ("IsEnable") { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

and

CheckBox chk = new CheckBox();
Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

很明显,第一个代码不能重构,但第二个代码……