Discard feature significance in C# 7.0?

While going through new C# 7.0 features, I stuck up with discard feature. It says:

Discards are local variables which you can assign but cannot read from. i.e. they are “write-only” local variables.

and, then, an example follows:

if (bool.TryParse("TRUE", out bool _))

What is real use case when this will be beneficial? I mean what if I would have defined it in normal way, say:

if (bool.TryParse("TRUE", out bool isOK))

Answer

The discards are basically a way to intentionally ignore local variables which are irrelevant for the purposes of the code being produced. It’s like when you call a method that returns a value but, since you are interested only in the underlying operations it performs, you don’t assign its output to a local variable defined in the caller method, for example:

public static void Main(string[] args)
{
    // I want to modify the records but I'm not interested
    // in knowing how many of them have been modified.
    ModifyRecords();
}

public static Int32 ModifyRecords()
{
    Int32 affectedRecords = 0;

    for (Int32 i = 0; i < s_Records.Count; ++i)
    {
        Record r = s_Records[i];

        if (String.IsNullOrWhiteSpace(r.Name))
        {
            r.Name = "Default Name";
            ++affectedRecords;
        }
    }

    return affectedRecords;
}

Actually, I would call it a cosmetic feature… in the sense that it’s a design time feature (the computations concerning the discarded variables are performed anyway) that helps keeping the code clear, readable and easy to maintain.

I find the example shown in the link you provided kinda misleading. If I try to parse a String as a Boolean, chances are I want to use the parsed value somewhere in my code. Otherwise I would just try to see if the String corresponds to the text representation of a Boolean (a regular expression, for example… even a simple if statement could do the job if casing is properly handled). I’m far from saying that this never happens or that it’s a bad practice, I’m just saying it’s not the most common coding pattern you may need to produce.

The example provided in this article, on the opposite, really shows the full potential of this feature:

public static void Main()
{
    var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
    Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1: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 (year2 == 2010) {
            population2 = 8175133;
        }

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

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

From what I can see reading the above code, it seems that the discards have a higher sinergy with other paradigms introduced in the most recent versions of C# like tuples deconstruction.


For Matlab programmers, discards are far from being a new concept because the programming language implements them since very, very, very long time (probably since the beginning, but I can’t say for sure). The official documentation describes them as follows (link here):

Request all three possible outputs from the fileparts function:

helpFile = which('help');
[helpPath,name,ext] = fileparts('C:Pathdata.txt');

The current workspace now contains three variables from fileparts: helpPath, name, and ext. In this case, the variables are small. However, some functions return results that use much more memory. If you do not need those variables, they waste space on your system.

Ignore the first output using a tilde (~):

[~,name,ext] = fileparts(helpFile);

The only difference is that, in Matlab, inner computations for discarded outputs are normally skipped because output arguments are flexible and you can know how many and which one of them have been requested by the caller.