丢弃和不分配变量有什么区别?

What is the difference between discard and not assigning a variable?

在 c# 7.0 中,您可以使用丢弃。使用丢弃和不分配变量有什么区别?

public List<string> DoSomething(List<string> aList)
{ 
//does something and return the same list
}
_ = DoSomething(myList);
DoSomething(myList);

有区别吗?

丢弃更多的是您不关心的 out 参数。例如:

if (int.TryParse(123, out _))
{
   ....
}

它们的存在实际上只是为了防止您不得不声明一个您不使用的变量。所以上面的旧方法是:

int throwAway;
if (int.TryParse(123, out throwAway))
{
   ....
}

引用the docs:

Because there is only a single discard variable, and that variable may not even be allocated storage, discards can reduce memory allocations. Because they make the intent of your code clear, they enhance its readability and maintainability.

所以丢弃是 memory-efficient(尽管这 )(不要将此作为优化;IMO 这在很大程度上属于 过早优化,因为效率增益很小)但更重要的是,它们通过明确表示您不打算对变量做任何事情来使您的代码更具可读性。

以下两行在编译级别没有区别。

_ = foo();
foo();

IDE 级别的细微差别:foo(); 可能会在 Visual Studio 晚于 2019 年显示警告,因为您没有使用函数的 return 值。

根据 MSDN,

discards can reduce memory allocations. Because they make the intent of your code clear, they enhance its readability and maintainability.

参考:https://docs.microsoft.com/en-us/dotnet/csharp/discards

关注 link 也可能有所帮助。

it seems that the discards have a higher sinergy with other paradigms introduced in the most recent versions of C# like tuples deconstruction.

参考:

这两行代码完全没有区别。
它们都翻译成完全相同的 IL:

public void A(List<string> myList)
{
    _ = DoSomething(myList);
}

public void B(List<string> myList)
{
    DoSomething(myList);
}

两者都翻译成:

IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call instance class [System.Private.CoreLib]System.Collections.Generic.List`1<string> C::DoSomething(class [System.Private.CoreLib]System.Collections.Generic.List`1<string>)
IL_0007: pop
IL_0008: ret

你可以在SharpLab
上自己看看 (注:我其实看不懂IL,但这是A和B两种方法的结果)

正如 Liam 在他的回答中所写,丢弃对于 out 您不打算使用的参数、元组解构、模式匹配和开关表达式很有用。
您可以在 official documentation.

中阅读所有相关信息

根据 Liam 的评论更新: 请注意,我仅指此特定场景。
按预期使用时,舍弃 memory-efficient and/or 可提高代码的可读性。