Pierre-olivier Gendraud
Pierre-olivier Gendraud

Reputation: 1927

How to return a named tuple with only one field

I wrote a function in c# which initially returned a named tuple. But now, I only need one field of this tuple and I would like to keep the name because it helps me to understand my code.

private static (bool informationAboutTheExecution, bool field2thatIdontNeedAnymore) doSomething() {
        // do something
        return (true, false);
    }

This function compile. But It's the following function that I want

private static (bool informationAboutTheExecution) doSomething() {
        // do something
        return (true);
    }

the error messages:

Tuple must containt at least two elements

cannot implcitly convvert type 'bool' to '(informationAboutTheExecution,?)

Has somebody a solution to keep the name of the returned value?

Upvotes: 14

Views: 2830

Answers (4)

akash kubavat
akash kubavat

Reputation: 847

It's an old thread but just thought to add my point. It is for C# 7.0 (and later)

If you always want to return one result/value then you could supply the second return parameter as "_". Portions of a tuple assignment can be excluded using an underscore; this is called a discard.

Ref: https://learn.microsoft.com/en-us/archive/msdn-magazine/2017/august/essential-net-csharp-7-0-tuples-explained

In your case, your code is

private static (bool informationAboutTheExecution, bool field2thatIdontNeedAnymore) doSomething() {
        // do something
        return (true, false);
    }

In the calling method, say you always ignore the 2nd parameter then you can use like:

(bool xyz, _) = doSomething();

or if you want 2nd parameter to be returned then

(_, bool xyz) = doSomething();

In this, you don't even need to change the actual method code.

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460238

I just want to add another option, althought he out is the easiest workaround and Marc explained already why it's not possible. I would simply create a class for it:

public class ExecutionResult
{
    public bool InformationAboutTheExecution { get; set; }
}

private static ExecutionResult DoSomething()
{
    // do something
    return new ExecutionResult{ InformationAboutTheExecution = true };
}

The class can be extended easily and you could also ensure that it's never null and can be created with factory methods like these for example:

public class SuccessfulExecution: ExecutionResult
{
    public static ExecutionResult Create() => new ExecutionResult{ InformationAboutTheExecution = true };
}
public class FailedExecution : ExecutionResult
{
    public static ExecutionResult Create() => new ExecutionResult { InformationAboutTheExecution = false };
}

Now you can write code like this:

private static ExecutionResult DoSomething()
{
    // do something
    return SuccessfulExecution.Create();
}

and in case of an error(for example) you can add a ErrorMesage property:

private static ExecutionResult DoSomething()
{
    try
    {
        // do something
        return SuccessfulExecution.Create();
    }
    catch(Exception ex)
    {
        // build your error-message here and log it also
        return FailedExecution.Create(errorMessage);
    }
}

Upvotes: 10

Nailuj29
Nailuj29

Reputation: 888

If you must name your return, you can do this:

private static void doSomething(out bool information) {
    // do something
    information = true;
}

then call it with

bool result;
doSomething(out result);

Upvotes: 6

Marc Gravell
Marc Gravell

Reputation: 1063774

You cannot, basically. You can return a ValueTuple<bool>, but that doesn't have names. You can't add [return:TupleElementNamesAttribute] manually, as the compiler explicitly does not let you (CS8138). You could just return bool. You can do the following, but it isn't any more helpful than just returning bool:

    private static ValueTuple<bool> doSomething()
        => new ValueTuple<bool>(true);

Part of the problem is that ({some expression}) is already a valid expression before value-tuple syntax was introduced, which is why

    private static ValueTuple<bool> doSomething()
        => (true);

is not allowed.

Upvotes: 11

Related Questions