【问题标题】:What is the difference between discard and not assigning a variable?丢弃和不分配变量有什么区别?
【发布时间】:2021-01-27 13:16:10
【问题描述】:

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

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

有什么不同吗?

【问题讨论】:

  • 几乎可以肯定没有区别。在这个例子中,语言已经提供了一种不使用变量的方法。在所有情况下,即使不需要变量,通常也需要变量的实际值。例如,模式匹配元组的一个元素但不匹配另一个元素。

标签: c# c#-7.0


【解决方案1】:

这两行代码绝对没有区别。
它们都转换为完全相同的 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 参数、元组解构、模式匹配和 switch 表达式,丢弃很有用。
您可以在official documentation.

中阅读所有相关信息

根据 Liam 的评论更新: 请注意,我仅指的是这种特定情况。
当按预期使用时,丢弃可以节省内存和/或提高代码的可读性。

【讨论】:

  • 所以“内存效率”的说法似乎是错误的?
  • 我怀疑“可能甚至没有分配存储空间”
  • 不,它们在按预期使用时内存效率很高(用于输出参数等),只是在这种特定情况下它们是多余的。
【解决方案2】:

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

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

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

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

引用the docs

因为只有一个丢弃变量,并且该变量甚至可能没有分配存储空间,所以丢弃可以减少内存分配。因为它们使代码的意图清晰,所以它们增强了代码的可读性和可维护性。

所以丢弃是内存效率的(尽管这是depends on usage)(不要将其作为优化;IMO 这非常属于过早优化的领域,因为效率增益是很小),但更重要的是,它们使您的代码更易读,因为它们明显表明您不打算对变量做任何事情。

【讨论】:

  • 如果您只想测试字符串是否为数字,使用正则表达式可能会更好。虽然我没有像评论文档中的用例那样评论你的答案。
  • @CaptainKenpachi 在什么方面更好?使用正则表达式可能会在内存使用方面花费更多,并且不要让我开始了解代码的可读性。不要忘记这个-3.14e3 是一个有效的整数。 Check out this SO post
  • 您会惊讶于 .TryParse 引擎盖下发生的事情。 stackoverflow.com/questions/15294878/…
  • TBH 我会选择正则表达式而不是尝试基于可读性而不是优化的解析。基于premature optimisation being the root of all bad things and all
  • @CaptainKenpachi int.TryParse 不使用正则表达式这一事实表明最好不要使用正则表达式。我不太关心进行性能测试,我完全同意 Liam 的评论。我会随时选择可读性而不是性能,除非在编写性能关键代码时——即使这样——我也会从可读代码开始,并在需要时从那里开始改进它的性能。
【解决方案3】:

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

_ = foo();
foo();

IDE 级别的细微差别:foo(); 可以在 2019 年以后的 Visual Studio 中显示警告,因为您没有使用函数的返回值。

根据 MSDN,

丢弃可以减少内存分配。因为他们做出了意图 您的代码清晰,它们增强了它的可读性和可维护性。

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

以下链接也可能有所帮助。

似乎丢弃与其他范式有更高的协同作用 在最新版本的 C# 中引入,例如元组 解构。

参考:Discard feature significance in C# 7.0?

【讨论】:

猜你喜欢
  • 2011-03-20
  • 2019-02-28
  • 2021-08-14
  • 1970-01-01
  • 2013-04-11
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多