Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of discards in c#

Tags:

c#

I've just come across discards in c# and am wondering a couple things that I feel Microsoft Docs on Discards didn't explain very well.

  1. With a standalone discard is it just meant for readability? If I had a function that returned a result (that isn't necessarily needed), let's say a bool or int, but also did some other logic then why use a discard when you can simply call the function outside of an assignment?

For example:

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);

Don't they both just discard the result anyways? This looks like it is purely a preference thing to me.

  1. In Microsoft's documentation about discards it is eluded that it'll reduce memory allocations is this because they are equivalent to unassigned variables?
  2. What are the performance benefits of discards if there are any and it is it just a stylistic thing meant to improve readability?

Edit:

To be more clear: I'm just curious if there are any potential performance benefits to using discards. The Microsoft doc link that I provided states "there is only a single discard variable, and that variable may not even be allocated storage, discards can reduce memory allocations", in which use case (pattern matching, calls to methods with out, tuple deconstruction and/or standalone) are memory allocations reduced?

like image 323
Jonathan Van Dam Avatar asked Apr 15 '19 16:04

Jonathan Van Dam


2 Answers

In general, there is no sense to use discard in this sentence:

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

since you can just ignore the return value. I did never anyone using standalone discards, but the documentation covers some specific cases when it can be useful.

The discards are used when you have to provide a variable, but don't need it.
As already covered in the provided documentation page, discards are very useful for:

Pattern matching

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

Methods with out parameters

If you want to check if you can parse a string to an integer, but don't care about the result:

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

Otherwise, you would have to declare an out variable, which you wouldn't use and which would consume some memory.

Deconstruction

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

Without discards you would deconstruct the result into 3 different variables, and use only one of them. With discards the code has cleaner intentions and more ineffective in terms of memory management.

like image 63
Yeldar Kurmangaliyev Avatar answered Nov 17 '22 23:11

Yeldar Kurmangaliyev


I believe this deals more with initial memory allocation rather than JUST memory management. So if you do not consume the output variable then it is still going to pushed onto the stack regardless if it is a ref type. (Yeah so the val types in your question won't be and I see your point there.) but if you are dealing with something like a filestream and didn't close the stream then I believe you are going to be holding onto that for the application lifecycle. That said then you have to be conscious of anything implementing IDisposable. I would think that discards could have a relatively bigger impact in that regard.

Past that, dealing with out params passed into functions, it prevents the initial memory allocation of those variables since you won't be using them. It may not have a huge impact on smaller projects but if you have some method that is used excessively across an application then it's use is more applicable than just some new trendy style.

like image 25
Travis Acton Avatar answered Nov 17 '22 21:11

Travis Acton