使用“value"作为c#中的标识符
本文关键字:标识符 作为 value quot 使用 | 更新日期: 2023-09-27 18:02:25
在编写简短的辅助函数时,我经常发现自己希望使用变量标识符"value"作为参数。当我这样做时,似乎Visual Studio编译得很好,并且没有任何抱怨:
public void MyMethod(int value, bool option, string message)
{
value = 1;
// More code...
}
然而,Visual Studio抱怨如下(如预期的):
private int _myProperty;
public int MyProperty
{
get
{
return _myProperty;
}
set
{
int value = 0;
_myProperty = value;
}
}
这让我相信,"值"被视为关键字(或不是)取决于上下文。我对c#相当陌生,据我所知,我还没有在其他语言中见过上下文特定的关键字。
问题:在属性设置器之外使用"value"作为变量名是否总是安全的?如果没有,什么时候可以安全地进行?这通常被认为是不好的做法吗?
我很惊讶,我不能找到这个问题已经问过SO,我怀疑有人问过它之前。然而,由于许多帖子的标题中有"变量"answers"标识符",因此很难搜索。我无法在MSDN上找到有关此信息。
EDIT:最后一个问题是要问经常还是通常不赞成。它已被更改以反映这一点。
的MSDN说:
set访问器类似于返回类型为void的方法。它使用一个名为value的隐式形参,其类型是属性的类型。
属性基本上是语法糖,避免了你必须编写大量的get_Bar
和set_Bar
方法(注意:还有一些其他的优点,CLR知道它是一个属性)。例如,如果您有这样一个类:
public class Foo
{
private int _bar;
public int Bar
{
get { return _bar; }
set { _bar = value; }
}
}
它将生成IL(用于setter),看起来像这样:
.method public hidebysig specialname
instance void set_Bar(int32 'value') cil managed
{
//
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: stfld int32 Program/Foo::_bar
IL_0008: ret
} // end of method Foo::set_Bar
这里需要注意的是,set_Bar
方法接受一个名为value
的参数。因此,它不仅"类似"一个返回类型为void并带有一个名为value
的参数的方法,它实际上就是。
显然,你不能在setter中使用value
。
现在你应该在其他地方使用它吗?视情况而定。如果在你使用它的上下文中它指的是什么很明显,那么当然。如果value
在特定上下文中是不明确的,则使用更明确的内容。
上下文关键字值在普通属性声明的set访问器中使用。
没有提到将value
视为关键字的任何其他上下文中,因此除了setter、或其他可能已经定义了的地方之外,您应该可以使用value
。这是不好的练习吗?不作为规则,不超过任何其他可能有歧义的变量名。
编辑:一个地方,我认为有value
作为一个名字将是真正有问题的将作为一个字段(或更糟糕的属性)在一个类。例如:
public class Foo
{
private int value;
public int Value
{
get { return value; }
set { value = value; } // which `value` are you setting? and to what?
}
}
现在你可以用this.value = value
来消除这里的歧义,但它仍然很难看,对我来说,最好为你的字段使用不同的名称。
在属性设置器中,变量名value
是保留的。它被用作变量的名称,该变量可以分配给后备字段。
问题:在属性setter之外使用"value"作为变量名总是安全的吗?如果没有,什么时候可以安全地进行?这被认为是不好的做法吗?
只在属性设置器中保留。这是一个非常通用的名称,但它通常是您正在使用的变量的最佳描述。
MSDN info
在set
访问器之外的任何地方使用value
作为标识符都是可以的。c#语言规范(链接旧版本)说:
由于set访问器隐式地有一个名为
value
的形参,这是局部变量或常量的编译时错误在set访问器中声明该名称。
Word value
在c#中不是(也从来不是)一个完整关键字,即使它从c# 1开始就在setter中有这种特殊用途。
参见value
(c# Reference)获取更多信息。
当然,如果您有一个名为value
的字段(类级变量),并且您希望从set
访问器中访问它,请使用this.value
(或NameOfYourType.value
用于static
字段)。
有关实际关键字和上下文"关键字"的列表,请参见c# keywords。
c#有很多上下文关键字。在语言的新版本中使用它们的主要原因是避免对现有编译代码进行破坏性更改。上下文关键字允许他们添加新的语义,而不会破坏以前有效的代码。
正如Eric的文章中提到的,您总是可以使用@
作为前缀,以便能够使用关键字作为标识符。我认为这样做的主要优点是能够与其他用其他CLR语言开发的具有不同关键字集的库进行互操作,其中c#关键字(保留的或上下文的)可能不是其他语言中的关键字。
正如其他人回答的那样,value是为属性保留的,但是值不是专门为方法保留的,因此,除了属性setter
之外,您可以在任何地方使用变量value但是,如果你在get中设置value,它就会工作得很好。
好public int MyProperty { get { int value = 0; return value; }}
不好public int MyProperty { get { ... } set { int value = 0; _MyProperty = value }}
c#有两种关键字:全局关键字和上下文关键字。
全局关键字永远不能用作标识符。上下文关键字仅在某些情况下保留。例如,当编译器看到代码不是查询时,您可以使用大多数LINQ关键字作为变量或方法名。
value仅在属性设置器中作为参数名保留。在其他任何地方都可以使用它作为标识符,这通常是有意义的。我认为这个关键字的上下文不太可能扩展,因为很多程序使用它作为参数名,没有人喜欢破坏更改