views:

104

answers:

5

Assuming a method with the following signature

bool TryXxxx(object something, out int toReturn)

What is it acceptable for toReturn to be if TryXxxx returns false?

In that it's infered that toReturn should never be used if TryXxxx fails does it matter?

If toReturn was a nulable type, then it would make sense to return null. But int isn't nullable and I don't want to have to force it to be.

If toReturn is always a certain value if TryXxxx fails we risk having the position where 2 values could be considered to indicate the same thing. I can see this leading to potential possible confusion if the 'default' value was returned as a valid response (when TryXxxx returns true).

From an implementation point if view it looks like having toReturn be a[ny] value is easiest, but is there anything more important to consider?

+4  A: 

It could be default(int):

bool TryXxxx(object something, out int toReturn)
{
    toReturn = default(int);
    return false;
}
Darin Dimitrov
+2  A: 

I would say default, but really it shouldn't matter. The convention with the TryX is that the caller should check the return value and only use the out parameter when the method returns true.

Brian Rasmussen
+2  A: 

Basically it is something. I would document it as "not defined". Sensible values are:

  • default()
  • Minvalue, MaxCValue, NEWvalue (as new int ()), null
  • NAN value (Double.NaN)

But in general, I woul really say "not defined" and not give people something they may try to rely on.

TomTom
In theory, you can document the method as giving "undefined" behavior, but in reality you need to provide a concrete implementation. Yes, you could return a random value, to perhaps provoke dormant bugs to surface, but a practical solution is usually to return a fixed, default value, hence "default(T)" is probably the best value. Also note that in this case, you could still document the method as giving undefined behavior, which gives you the option of changing the value later, if necessary. I would, however, probably return a fixed default myself.
Lasse V. Karlsen
+6  A: 

I would explicitly document it as using the default value for the type (whatever that type is; so 0 in this case but default(T) in a more general case). There are various cases where the default value is exactly what you want if the value isn't present - and in that case you can just ignore the return value from the method.

Note that this is what methods like int.TryParse and Dictionary.TryGetValue do.

Jon Skeet
And besides, if you care about the result enough that you don't want to use default, unless that was explicitly the value that was XYZ (parsed, etc.), then you really should be checking the return value from the method anyway.
Lasse V. Karlsen
Hadn't thought about the consumer having a reason to use the returned value if Try returned false.
Matt Lacey
A: 

1) Actually, I think it should not matter because you should always check the boolean result of those methods before processing the value. That's what the TryXXX methods are for.

2) However, in such cases, I always refer to the implementation in the .NET framework to guarantee consistency. And a quick look into Reflector shows that the Int32 type returns 0 if parsing failed:

internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result)
{
    byte* stackBuffer = stackalloc byte[1 * 0x72];
    NumberBuffer number = new NumberBuffer(stackBuffer);
    result = 0; // <== see here!
    if (!TryStringToNumber(s, style, ref number, info, false))
    {
        return false;
    }
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
    {
        if (!HexNumberToInt32(ref number, ref result))
        {
            return false;
        }
    }
    else if (!NumberToInt32(ref number, ref result))
    {
        return false;
    }
    return true;
}

However, not knowing the implementation details, it might still happen that the parsing problem occurs when a value has already been assigned (partly). In this case, the value might no longer be 0. Therefore, you should always stick to "solution" 1)! :-)

gehho.

gehho