版本6.0有一个新功能nameof,但我无法理解它的目的,因为它只需要变量名称并在编译时将其更改为字符串.
我认为它在使用<T>时可能有一些用途,但是当我尝试nameof(T)它时只打印一个T而不是使用的类型.
有意的吗?
浏览,搜索和希望但找不到直接答案.
无论如何在C#6.0中使用nameofwithouth指定方法名称来获取当前方法名称?
我将测试结果添加到这样的字典中:
Results.Add(nameof(Process_AddingTwoConsents_ThreeExpectedRowsAreWrittenToStream), result);
Run Code Online (Sandbox Code Playgroud)
我希望如果我不必明确指定方法名称,那么我可以复制+粘贴该行,这是一个非工作的例子:
Results.Add(nameof(this.GetExecutingMethod()), result);
Run Code Online (Sandbox Code Playgroud)
如果可能的话我不想使用Reflection.
UPDATE
这不是(如建议的)这个问题的副本.我问是否明确可以使用nameofwithout(!)反射来获取当前方法名称.
是否有推荐的方式来使用新的
nameof()
Run Code Online (Sandbox Code Playgroud)
在ASP.NET MVC中表达控制器名称?
Url.Action("ActionName", "Home") <------ works
Run Code Online (Sandbox Code Playgroud)
VS
Url.Action(nameof(ActionName), nameof(HomeController)) <----- doesn't work
Run Code Online (Sandbox Code Playgroud)
显然它不起作用因为nameof(HomeController)转换为"HomeController"而MVC需要的只是"Home".
想象一下根命名空间级别的类型(可能位于默认global空间中,或者可能是extern alias)。
使用别名前缀时,似乎无法通过 via 引用此类型。nameof()它可以与typeof, 以及通过using别名配合使用(尽管nameof在using别名上生成别名,而不是类型名称)。编译器反对 CS8083,“别名限定名称不是表达式”。
但是:这有理由吗?这是为了防止一些模糊的问题场景吗?或满足一些规范细节?或者这可能是一个编译器错误?我还非常满意地注意到,我们通常不应该在命名空间根中声明类型——CA1050这一点非常正确;但这不是重点:)
完整示例如下;请注意,在此示例中使用两个项目进行using别名检查,但为了简单起见,C在简单调查中可以忽略所有涉及的内容。
extern alias foo;
using System;
using X = global::A;
using Y = global::FunWithNamespaces.B;
using Z = foo::C;
public class A { }
namespace FunWithNamespaces
{
public class B { }
public class Program
{
static void Main()
{
// oddness is on the lines marked ## CS8083 …Run Code Online (Sandbox Code Playgroud) nameof(order.User.Age)仅返回"Age"而不是"order.User.Age"
以更有限的方式做到这一点的原因是什么?如果我们只想要姓氏,我们可以做类似的事情
public static GetLastName(this string x) {
return string.Split(x, '.').Last();
}
nameof(order.User.Age).GetLastName()
Run Code Online (Sandbox Code Playgroud)
有了一个操作员,我们可以同时获得"Age"和"order.User.Age".但是根据目前的实施情况,我们只能获得"年龄".
这个决定背后有一些逻辑吗?
编辑:例如,这种行为是MVC绑定所必需的
Html.TextBox(nameof(order.User.Age))
Run Code Online (Sandbox Code Playgroud) 我使用nameof函数将属性名称作为字符串,因此:
public bool IsRunning => ...;
...
RaisePropertyChanged(nameof(IsRunning));
Run Code Online (Sandbox Code Playgroud)
Resharper通过警告强调了这一点:
使用调用者信息属性传递给参数的显式参数
代码工作,我只是想知道上面的警告是否是我应该担心的事情.
C#6中最方便的新功能之一是nameof,它允许程序员有效地消除魔术字符串的使用.
根据文档,nameof返回一个字符串:
用于获取变量,类型或成员的简单(非限定)字符串名称.
在下面的代码示例中,通过显式输入可以正常工作:
string magicString = nameof(magicString);
Run Code Online (Sandbox Code Playgroud)
但是,在使用var关键字的隐式类型时:
var magicString = nameof(magicString);
Run Code Online (Sandbox Code Playgroud)
编译器抛出一个错误:
在声明之前不能使用局部变量'magicString'
然后,我对Visual Studio中提供的C#Interactive窗口进行了一些实验.同样,第一个例子运行正常,但第二个例子这次抛出了一个不同的错误:
错误CS7019:无法推断'magicString'的类型,因为其初始化程序直接或间接引用定义.
该nameof表达清楚返回一个字符串,那么为什么不能在编译器隐式键入它正与初始化变量使用时?
如果我错了,请纠正我,但要做类似的事情
var typeOfName = typeof(Foo).Name;
Run Code Online (Sandbox Code Playgroud)
和
var nameOfName = nameof(Foo);
Run Code Online (Sandbox Code Playgroud)
应该给你完全相同的输出.根据这个来源的一个可以理解的原因:https://msdn.microsoft.com/en-us/library/dn986596.aspx是那个
"使用nameof有助于在重命名定义时保持代码有效"
如果你想要得到的类实例的字符串是不是可以做这样的事情:
var fooInstance = new Foo();
var nameOfName = nameof(fooInstance);
Run Code Online (Sandbox Code Playgroud)
但是,你可以这样做:
static string GetName<T>(T item) where T : class
{
return typeof(T).GetProperties()[0].Name;
}
var typeOfName2 = GetName(new { fooInstance });
Run Code Online (Sandbox Code Playgroud)
在这两种情况下(typeof和nameof)都可以进行重构,所以我没有看到重新发明另一个更高级别关键字的任何其他原因,例如nameof,执行已经存在的事情.它们之间是否有任何差异,我没有清楚地看到?
最后,如果有人能指出我参考资料来了解其执行情况,我将不胜感激nameof.它使用反射吗?
更新1: 从这里采取
nameof显然与声明字符串变量一样有效.没有任何反思或任何反对!
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Run Code Online (Sandbox Code Playgroud)
当您查看生成的MSIL时,您将看到它等同于字符串声明,因为使用ldstr运算符将对字符串的对象引用推送到堆栈: …
采用以下类和方法:
public class Foo
public Foo Create(string bar) {
return new Foo(bar);
}
Run Code Online (Sandbox Code Playgroud)
所以获得"创造"是显而易见的: nameof(Foo.Create)
除了使用反射在运行时读取参数之外,有没有办法获得"bar"?
C#6.0引入了nameof()运算符,它返回一个字符串,表示放在其中的任何类/函数/方法/局部变量/属性标识符的名称.
如果我有这样的课程:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样使用运算符:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
Run Code Online (Sandbox Code Playgroud)
这很有用,因为在编译时检查了正确的字符串.如果我拼错某些属性/方法/变量的名称,编译器将返回错误.此外,如果我重构,所有字符串都会自动更新.有关实际用例,请参阅此文档.
Java中是否有该运算符的等价物?否则,我怎样才能达到相同的结果(或相似)?