score:2

Accepted answer

the error is pretty clear. both the "?" en ":" parts of that conditional operator need to have the same type or must at least be implicitly converted to the same type. and a lone null doesn't have a good type.

maybe you could use .firstordefault(). depending on the type of your res that would give a null or 0m.

score:0

in second case you can use res.firstordefault().

ienumerable<t>.firstordefault() returns first t in set or default<t> if set is empty: null for classes and some default value for structs, in common case - 0.

public decimal? get()
{
    var res = ...
    return res.firstordefault();
}

which is equal to

public decimal? get()
{
    var res = ...
    return res.count() > 0 ? res.first() : default(decimal?);
}

score:1

i'm guessing res is an array of decimals i.e. decimal[]. this would be because you have declared res like this:

var res = { 1.0, 2.0, 3.0 };

and not like this:

var res = { 1.0, 2.0, null };

so there is no reason for the compiler to think res is an array of nullable decimals.

now you are using a ternary operator which must always return the same (or an equivalent castable) type from both sides.

but as res.first() is a 'decimal' and your null by default is untyped it just makes your null equivalent to the type of your first argument (res.first() i.e. a decimal). by forcing the null to be typed as a nullable decimal ('decimal?') you are actually forcing the compiler to treat res.first() as a nullable decimal too.

however, a better solution overall for you is this:

public decimal? get()
{
    decimal?[] res = ...
    return res.firstordefault();
}

score:2

off-topic, but...

using count is a bit pointless when all you need to know is whether or not the sequence has any elements. count will loop through all the elements whereas any will stop as soon as it hits the first element:

public decimal? get()
{
    var res = ...
    return res.any() ? res.first() : (decimal?)null;
}

or maybe this:

public decimal? get()
{
    var res = ...
    using (var e = res.getenumerator())
    {
        return e.movenext() ? e.current : (decimal?)null;
    }
}

score:7

this behavior is covered in section 7.13 of the c# language spec.

in short the types of the two expressions in the ternary operator must be * compatible* in order for the compiler to determine the type of the ternary expression. in this case the two types being considered are

  1. decimal
  2. null

the decimal type is a value type and hence null is not convertible to it. the value null has no associated type. this prevents the compiler from determining the type of the expression and leads to a compilation error.

in the first example the second type is decimal?. there is a conversion between decimal and decimal? so the compiler picks decimal? as the type.


Related Query

More Query from same tag