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

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

知道目的吗?


当前回答

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

例子:

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

这句话的意思是:

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

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

其他回答

如果您想重用属性名,例如根据属性名抛出异常,或者处理PropertyChanged事件,该怎么办呢?在许多情况下,您都希望拥有属性的名称。

举个例子:

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

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

在第一种情况下,如果不同时更改属性定义和nameof(SomeProperty)表达式,则重命名SomeProperty将导致编译错误。在第二种情况下,重命名SomeOtherProperty或更改“SomeOtherProperty”字符串将导致无声地破坏运行时行为,在构建时没有错误或警告。

这是一种非常有用的方法,可以保持代码的编译和(在某种程度上)没有错误。

(Eric Lippert写了一篇很好的文章,为什么infoof没有入选,而nameof却入选了)

之前我们使用的是这样的东西:

// 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)
{
    ...
}

原因-编译时安全。没有人可以默默地重命名属性并破坏代码逻辑。现在我们可以使用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"

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

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

最常见的用法是在输入验证中,例如

//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参考)

MSDN文章列出了MVC路由(这个例子让我真正理解了这个概念)。(格式化的)描述段落如下:

当报告代码中的错误时, 连接模型-视图-控制器(MVC)链接, 触发属性改变事件,等等, 你经常想要 捕获方法的字符串名称。使用nameof有助于保存代码 在重命名定义时有效。 在你必须使用字符串字面量之前 来引用定义,这在重命名代码元素时是很脆弱的 因为工具不知道检查这些字符串字面量。

公认的/评分最高的答案已经给出了几个很好的具体例子。