nameof和typeof之间的区别 [英] Difference between nameof and typeof

查看:79
本文介绍了nameof和typeof之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我做错了,请纠正我,但是要做类似的事情

Correct me if I am wrong, but doing something like

var typeOfName = typeof(Foo).Name;

var nameOfName = nameof(Foo);

应该给您完全相同的输出.根据此来源可以理解的原因之一: https://msdn.microsoft.com/en-us/library/dn986596.aspx

should give you exactly the same output. One of the understandable reasons according to this source: https://msdn.microsoft.com/en-us/library/dn986596.aspx is that

使用nameof可以在重命名定义时使代码保持有效"

"Using nameof helps keep your code valid when renaming definitions"

如果要以字符串形式获取类实例,则不能执行以下操作:

If you want to get the class instance as string it is not possible to do something like that:

var fooInstance = new Foo();
var nameOfName = nameof(fooInstance);

但是,您可以执行以下操作:

however, you can do something like:

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}
var typeOfName2 = GetName(new { fooInstance });

在两种情况下( typeof nameof )都可以进行重构,所以我看不出有其他理由重新发明另一个更高级别的关键字,例如 nameof,以执行已经存在的操作.他们之间有没有我看不到的区别?

In both cases (typeof and nameof) a refactoring is possible, so I dont see any other reason for reinventing another higher level keyword, such as nameof, to perform something that already exists. Are there any differences between them that I don't clearly see?

最后,如果有人可以将我指向参考源,以了解 nameof 的实现,我将不胜感激.它使用反射吗?

Finally, I would appreciate if could someone point me to a reference source to have a look at the implementation of nameof. Does it use Reflection?

更新1:取自此处

nameof 显然和声明字符串变量一样有效.没有反射或任何东西!

nameof is apparently as efficient as declaring a string variable. No reflection or whatsoever!

var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console

当您检查生成的MSIL时,您会发现它等同于字符串声明,因为使用ldstr运算符将对字符串的对象引用压入堆栈:

When you check out the MSIL generated you will see that it is equivalent to a string declaration because an object reference to a string gets pushed to the stack using the ldstr operator:

IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)

推荐答案

两个原因:

nameof 变成一个编译时常量. typeof(...).Name 需要一些反思.它不是太贵,但在某些情况下可能会造成伤害.

nameof turns into a compile-time constant. typeof(...).Name requires a bit of reflection. It's not overly expensive, but it can hurt in some cases.

第二,除了类型名称,它还用于其他用途.例如,参数:

Second, it's used for other things than type names. For example, arguments:

void SomeMethod(int myArgument)
{
  Debug.WriteLine(nameof(myArgument));
}

您还可以获取班级成员甚至本地人的名字.不用说,这对于调试信息非常有用.这也是在例如解析表达式树(不幸的是,在我要使用它的项目中,我们仍然停留在使用C#5的.NET 4.0上-可以在这里和那里省去一些麻烦).

You can also get the name of class members and even locals. Needless to say, this is quite useful for debugging information. It's also one of the ways to implement less fragile reflection when e.g. parsing expression trees (sadly, on the project where I'd use this, we're still stuck on .NET 4.0 with C# 5 - it'd save me a few hacks here and there).

为了消除混乱, nameof 不是一个函数, typeof 也不是.它是一个编译时运算符,并且始终在编译时进行评估(尽管很明显,泛型在时间上将编译时"移得更远了.)

And to clear up some confusion, nameof is not a function, and neither is typeof. It's a compile-time operator, and it's always evaluated at compile-time (though obviously, generics move the "compile-time" a bit further in time).

这篇关于nameof和typeof之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆