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.
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.
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?
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:
switch (stream)
{
case MemoryStream _:
case FileStream _:
ProcessStream(stream);
break;
}
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.
(_, _, 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With