我在 C# 中遇到了一个小问题,这只是一个复制粘贴错误,但不知道为什么 C# 接受了它。
这段代码居然能够成功编译... 究竟是为什么呢?
namespace DemoNS
{
class DemoClass
{
String _ = new String('a', 1);
}
}
变量名为 _
有默认的特殊含义吗?
我在 C# 中遇到了一个小问题,这只是一个复制粘贴错误,但不知道为什么 C# 接受了它。
这段代码居然能够成功编译... 究竟是为什么呢?
namespace DemoNS
{
class DemoClass
{
String _ = new String('a', 1);
}
}
变量名为 _
有默认的特殊含义吗?
现今,随着 C# 7.0 的推出,下划线符号_
的意义有时是重要的。它成为了新特性out var
的 丢弃运算符(discard operator)。当函数返回一个值,而你并不会使用它时,你可以使用这个符号向编译器发出信号,以便优化掉这个值。或者在解构操作中(又是 C# 7.0 的新功能),你可以使用它来忽略你不感兴趣的元组部分。
例子:
out var
void Test(out int i) => i = 1;
Test(out _); // _ was never declared, it will still compile in C# 7.0
var r = _; // error CS0103: The name '_' does not exist in the current context
示例:解构元组
var Person = ("John", "Smith");
var (First, _) = Person; // '_' is not a declared
Debug.Print(First); // prints "John"
Debug.Print(_); // error CS0103: The name '_' does not exist in the current context
如果你声明了自己的名为_
的变量,然后使用丢弃运算符,就会导致歧义问题。该问题已在此处报告。
编辑
如@maf-soft在评论中指出,上述问题并不是问题。如果声明了_
,它就像C# 7.0之前一样被视为普通变量。
编辑2021有点过期了
在c# 8.0中,_
也成为switch表达式中的通配符运算符,正式命名为丢弃运算符。
示例丢弃运算符var moreThan20 = val switch
{
>20 => "Yes",
>50 => "Yes - way more!",
_ => "No",
};
< p > < em > 丢弃运算符 在没有其他模式匹配时分配一个值 void
关键字 :) - maf-soft不,没有默认的意义,_
就像其他变量名一样。
我喜欢将其用于类似于Prolog匿名变量的方式:当你创建一个忽略其中一个参数的lambda表达式时,你可以将其命名为_
:
EventHandler handler = (_, e) => Console.WriteLine(e);
另一方面,我不会在其他地方使用它,你应该使用一个描述性的名称。
编辑:请注意,在C# 7.0中,“_”有时具有特殊含义。例如,您可以编写_ = new String('a', 1);
,即使您没有声明名为_
的变量。
之前的回答都很有用,但我认为它们忽略了一个使用情况。如果你不想使用函数的返回值,你可以使用_
字符,例如:
用下面的方式代替:
int returnvalue = RandomFunction();
你可以做
_ = RandomFunction();
_ = RandomFunction();
相对于 RandomFunction();
(即根本不分配返回值) 的好处是什么? - Marteng_ = GetUsers();
对我来说,这段代码意味着存在副作用,否则我们为什么要丢弃返回值?另一方面,如果我们有一个“命令”:
_ = DeleteAllUsers();
在这种情况下,我们只是将完全干净的命令调用变得视觉上看起来像一个查询。在lambda表达式或表示将未使用的参数时,我认为它的效果更好,但对于任何阅读者,也许不要到处都使用这些... - Oscar LundbergDeleteAllUsers();
应该是一个返回 void
的函数;_ = DeleteAllUsers();
应该是编译器错误。如果 GetUsers();
没有副作用但返回一个值,那么调用它却不使用返回值是毫无意义的。在这两种情况下,都不会编写你展示的代码。唯一需要使用 _ = SomeFunction();
的时候 是 如果正在为其副作用而调用该函数,但其返回值不需要。_ =
告诉未来的程序员:“我正在调用此函数以获得其副作用”。 - ToolmakerSteve_ =
正如此答案所说的那样:表明程序员有意忽略了返回值。 - ToolmakerSteve_
是一个有效的字符,与 a
或 i
相同。在语法上,变量可以以 _
开头,因此单个字符名 _
完全符合语法要求。虽然不是一个非常好的选择,但它可以编译并正常工作。
这是一个占位变量,没有被使用。它告诉编译器我们对输出值不感兴趣。
例子:创建了一个文件处理类。构造函数将启动该过程。我们有复制、删除操作。假设有一个特定的类负责启动该过程,但不需要担心其他操作。那么我会声明像这样:_ = new FileListener(); 我不用担心输出。 其他类可以实例化FileListener obj = new FileListener(); 或调用其他操作如 FileListener.CopyFile()。 class Program
{
static void Main(string[] args)
{
/// Ignore the instance value but initialized the operation by instantiation
_ = new FileListener();
Console.WriteLine("Hello World!");
}
}
public class FileListener
{
public FileListener()
{
/// Logic to listen external file changes
}
public static void DeleteFile()
{ }
public static void CopyFile()
{ }
}