在编写简短的帮助函数时,我经常发现自己想要使用变量标识符“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”用作属性设置器之外的变量名称是否总是安全的?如果没有,何时可以安全地完成?而且,这通常被认为是不好的做法吗?
我很惊讶我没有找到这个问题已经问过,我怀疑有人之前曾问过这个问题。但是,搜索很困难,因为标题中有很多帖子有“变量”和“标识符”。我无法在MSDN上找到有关此内容的信息。
编辑:最后一个问题是要询问经常或通常不赞成。它已经改变以反映这一点。
答案 0 :(得分:22)
在属性设置器中,保留变量名value
。它用作可以分配给支持字段的变量名称。
问题:在属性设置器之外使用“value”作为变量名是否总是安全的?如果没有,何时可以安全地完成?而且,这被认为是不好的做法吗?
它只保留在属性设置器中。这是一个非常通用的名称,但它通常可以是您正在使用的变量的最佳描述。
答案 1 :(得分:22)
这是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
的参数。所以它不仅类似于#34;一个返回类型为void且带有名为value
的参数的方法,实际上就是那个。
因此,显然,您无法将value
用于设置器中的其他内容。
现在你应该在其他地方使用它吗?这取决于。如果它在您使用它的上下文中明显指出了什么,那么肯定。如果value
在特定上下文中不明确,则使用更明确的内容。
来自MSDN:
contextual关键字值在普通属性声明中的set accessor中使用。
它没有提及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
删除这里的含糊之处,但它仍然很难看,我觉得为你的字段使用不同的名称似乎更好。
答案 2 :(得分:8)
在value
访问者之外的任何地方使用set
作为标识符都可以。 C# Language Specification (linking old version)说:
由于set访问器隐式具有名为
value
的参数, 它是局部变量或常量的编译时错误 在set访问器中声明具有该名称。
Word value
不是(也绝不是)C#中的完整关键字,即使它自C#1以来在setter中有特殊用途。
有关详情,请参阅value
(C# Reference)。
当然,如果您有一个名为value
的字段(类级变量)并且想要从set
访问者中访问它,请使用this.value
(或{{1 } NameOfYourType.value
字段)。
有关真实关键字和上下文“关键字”的列表,另请参阅C# Keywords。
答案 3 :(得分:2)
C# has lots of contextual keywords. The main reason for them in new versions of the language is to avoid breaking changes with existing compiling code. Contextual keywords lets them add new semantics, without breaking code that was previously valid.
As mentioned in Eric's article, you can always use @
as a prefix to be able to use a keyword as an identifier. I think the main advantage of that is the ability to interoperate with other libs that may have been developed in other CLR language with a different set of keywords, where a C# keyword (either reserved or contextual) may not be a keyword in that other language.
答案 4 :(得分:1)
正如其他已经回答的那样,值是为属性保留的,但是值并没有专门为方法保留,因此,除了属性setter之外,你可以在其他地方使用值
但是如果你在get中设置了值就可以了。
好
public int MyProperty { get { ... } set { int value = 0; _MyProperty = value }}
不好
git add .
答案 5 :(得分:1)
C#有两种类型的关键字:全局关键字和上下文关键字。
全局关键字可能永远不会用作标识符。上下文关键字仅在某些情况下保留。例如,当编译器发现代码不是查询时,您可以使用大多数LINQ关键字作为变量或方法名称。
值仅在属性设置器中保留为参数名称。您可以在其他任何地方使用它作为标识符,它通常是有意义的。我认为这个关键字的上下文不太可能扩展,因为很多程序都将它用作参数名称而且没有人喜欢破坏更改。