在c#

时间:2019-04-15 16:37:45

标签: c#

我刚刚在c#中遇到了一些丢弃物,并且想知道我觉得Microsoft Docs on Discards的一些解释不是很好。

  1. 使用独立的丢弃程序仅仅是为了提高可读性吗?如果我有一个返回结果的函数(不一定需要返回结果),假设是一个boolint,但是还做了其他一些逻辑,那么为什么当您可以简单地调用任务之外的功能?

例如:

TcpClient client = new TcpClient();
NetworkStream nc = tcpClient.GetStream();
// what's the difference between
nc.Read(someBuffer, 0, someSize);
// and the discard
_ = nc.Read(someBuffer, 0, someSize);

他们不是都只是放弃结果吗?看来这纯粹是我的偏爱。

  1. 在Microsoft有关丢弃的文档中,有人说它会减少内存分配,因为它们等同于未分配的变量吗?
  2. 如果有的话,丢弃的性能优势是什么?这仅仅是一种旨在提高可读性的样式问题?

编辑:

更明确地说:我只是好奇使用丢弃是否有任何潜在的性能优势。我提供的Microsoft doc链接指出“只有一个丢弃变量,并且可能甚至没有为该变量分配存储,丢弃可以减少内存分配”,在这种情况下(模式匹配,对方法的调用,out,元组解构)和/或独立)是否减少了内存分配?

3 个答案:

答案 0 :(得分:4)

通常,在这句话中没有意义使用丢弃:

_ = nc.Read(someBuffer, 0, someSize);

因为您可以忽略返回值。我从未使用过任何独立的丢弃程序,但是文档涵盖了一些有用的特定情况。

当您必须提供变量但不需要它时,将使用丢弃。
  如提供的文档页面中所述,丢弃对于以下内容非常有用:

模式匹配

switch (stream)
{
    case MemoryStream _:
    case FileStream _:
        ProcessStream(stream);
        break;
}

没有参数的方法

如果要检查是否可以将字符串解析为整数,但是不关心结果:

if (int.TryParse(str, out _))
{
    // do something
}

否则,您将必须声明一个out变量,该变量将不使用并且会消耗一些内存。

解构

(_, _, area) = city.GetCityInformation(cityName);

如果没有丢弃,则将结果分解为3个不同的变量,并且仅使用其中一个。使用丢弃时,代码的意图更简洁,并且在内存管理方面更加无效。

答案 1 :(得分:1)

丢弃等效于未分配的变量;他们没有价值。因为只有一个丢弃变量,并且可能甚至没有为该变量分配存储空间,所以丢弃可以减少内存分配。因为它们使您的代码意图清晰明了,所以它们提高了代码的可读性和可维护性。 从根本上讲,它们是一种忽略与执行操作无关的局部变量的方法,就像调用一个返回值的方法一样,但是,您只对它执行的基础操作感兴趣,您不使用该方法的返回。

正如我们在下面的示例中看到的那样,当您的应用程序代码使用一些元组元素但忽略其他元组元素时,丢弃在处理元组时特别有用:

  

注意:我已经从Microsoft docs获得了示例,并且提供了第二个输出只是为了显示差异

public class Example
{
   public static void Main()
   {
       var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
       var (cityName, _, year1, pop3, _, pop4) = QueryCityDataForYears("New York City", 1980, 2010);

       Console.WriteLine($"Population change, in 1960 to 2010: {pop2 - pop1:N0}");
       Console.WriteLine($"Population change, in {cityName}  from {year1} to 2010: {pop4 - pop3:N0}");
   }

    private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2)
    {
        int population1 = 0, population2 = 0;
        double area = 0;

        if (name == "New York City") 
        {
            area = 468.48; 
            if (year1 == 1960) 
            {
                population1 = 7781984;
            }
            if (year1 == 1980) 
            {
                population1 = 7981984;
            }
            if (year2 == 2010) 
            {
                population2 = 8175133;
            }

            return (name, area, year1, population1, year2, population2);
        }

        return ("", 0, 0, 0, 0, 0);
    }
}

//Output
//Population change, in 1960 to 2010: 393,149
//Population change, in New York City  from 1980 to 2010: 193,149

答案 2 :(得分:0)

我相信,这更多地涉及初始内存分配,而不是仅仅进行内存管理。因此,如果您不使用输出变量,那么无论它是ref类型,它都将继续被压入堆栈。 (是的,所以您的问题中的val类型不会出现,我明白您的意思了。)但是,如果您正在处理文件流之类的内容并且没有关闭流,那么我相信您将继续坚持下去应用程序生命周期。也就是说,您必须意识到实现IDisposable的所有方法。我认为,丢弃物在这方面可能产生相对较大的影响。

过去,处理不传递给函数的参数会阻止对这些变量进行初始内存分配,因为您将不会使用它们。它可能对较小的项目没有太大的影响,但是如果您有某种方法在整个应用程序中过度使用,那么它的使用将比仅仅一些新的流行风格更适用。