如何引用一个标识符,而无需编写成一个字符串在C#中的文字? [英] How to refer to an identifier without writing it into a string literal in C#?
问题描述
我常常想这样做:
<预类=郎-CS prettyprint-覆盖>
公共无效美孚(酒吧ARG)
{
抛出新的ArgumentException(的说法是不兼容+域名(富));
}
由于如果我改变富的名字IDE将重构我的错误消息太,如果我把一个字符串里面的方法(或任何其他类型的<击>成员击>标识符)的名称不会发生什么。我知道,实施名的唯一方法是通过使用反射,但我认为超过了mantainability增益性能损失,也不会涵盖所有种类的标识符。
括号之间的表达式的值可以计算在编译时(如typeof运算)和优化,成为一个字符串中通过改变语言规范的文字。你认为这是一个值得功能
PS:第一个例子使它看起来像的问题仅与例外,但它不是。想想你可能要参考一<击>类型成员击>识别每一种情况。 ?你必须通过一个字符串做吧
另外一个例子:
<预类=郎-cs prettyprint-覆盖>
[RuntimeAcessibleDocumentation(说明=类+域名(巴兹)+
它的工作。请参阅法+域名(DoItsJob)+的更多信息)]
公共类巴兹
{
[RuntimeAcessibleDocumentation(说明=此方法将只是假装+
做的工作,如果参数+域名(DoItsJob。 Arguments.justPretend)+
是真的。)]
公共无效DoItsJob(布尔justPretend)
{
如果(justPretend)
Logger.log(名称( justPretend)+是真的一事无成。);
}
}
更新:这个问题之前C#6被张贴,但可能仍然有效为那些谁正在使用的语言的早期版本。如果您正在使用C#6检查出来的 nameof
运营商,这确实几乎是同样的事情名称
运营商上面的例子。
C#的6版本引入了 nameof
算子的工作方式类似于名称
运营商问题的例子说明,但有一些限制。下面是从的 C#常见问题解答博客:
(如果x == NULL)抛出新的ArgumentNullException(nameof(X) );
您可以把更详细的带点名称在nameof的表情,但是这只是告诉编译器到哪里寻找:只有最后的标识将被用于:
块引用>
的WriteLine (nameof(person.Address.ZipCode)); //输出邮编
注:也有小设计变更nameof因为预览建成。在预览中,点缀表情就像在最后一个例子,其中人是在范围上一个变量,是不允许的。相反,你必须通过类型圆点
块引用>I often want to do this:
public void Foo(Bar arg) { throw new ArgumentException("Argument is incompatible with " + name(Foo)); }
Because if I change the name of Foo the IDE will refactor my error message too, what won't happen if I put the name of the method (or any other kind of
memberidentifier) inside a string literal. The only way I know of implementing "name" is by using reflection, but I think the performance loss outweighs the mantainability gain and it won't cover all kinds of identifiers.The value of the expression between parenthesis could be computed at compile time (like typeof) and optimized to become one string literal by changing the language specification. Do you think this is a worthy feature?
PS: The first example made it look like the question is related only to exceptions, but it is not. Think of every situation you may want to reference a
type memberidentifier. You'll have to do it through a string literal, right?Another example:
[RuntimeAcessibleDocumentation(Description="The class " + name(Baz) + " does its job. See method " + name(DoItsJob) + " for more info.")] public class Baz { [RuntimeAcessibleDocumentation(Description="This method will just pretend " + "doing its job if the argument " + name(DoItsJob.Arguments.justPretend) + " is true.")] public void DoItsJob(bool justPretend) { if (justPretend) Logger.log(name(justPretend) + "was true. Nothing done."); } }
UPDATE: this question was posted before C# 6, but may still be relevant for those who are using previous versions of the language. If you are using C# 6 check out the
nameof
operator, which does pretty much the same thing as thename
operator in the examples above.解决方案Version 6 of C# has introduced the
nameof
operator which works like thename
operator described in the examples of the question, but with some restrictions. Here are some examples and excerpts from the C# FAQ blog:(if x == null) throw new ArgumentNullException(nameof(x));
You can put more elaborate dotted names in a nameof expression, but that’s just to tell the compiler where to look: only the final identifier will be used:
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"
Note: there are small design changes to nameof since the Preview was built. In the preview, dotted expressions like in the last example, where person is a variable in scope, are not allowed. Instead you have to dot in through the type.
这篇关于如何引用一个标识符,而无需编写成一个字符串在C#中的文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!