I understand that you cannot have different types compounding into one result, but I don't understand why this is.
Eg.
Guid? ID;
int ID2;
var ID3 = ID ?? ID2;
The above code does not work, regardless of the nullability of ID
or the type of ID3
, var, object etc.
Can anyone explain why this isn't allowed?
My actual code looks like this:
public StandAloneMachine Get(int id, Guid? FKGuid = null, string FKName = "")
{
var parameters = new Parameters()
{
new Parameter("id", FKGuid ?? id)
};
}
Does anyone have a reason why this isn't allowed?
This is how the language is designed. What should it do? How'd you convert an int
, which is a 32-bit number, into a GUID
, which is a structure composed of several number portions, or vice-versa?
This code:
var ID3 = ID ?? ID2
translated into types means (pseudocode):
(inferred type_) = Guid? ?? int;
and the ??
operator naturally requires the types of its arguments to be compatible. The actual rules are fairly complex and can be found in the C# language specification here.
Anyway, the null-coalescing operator returns a single value and both its left and right arguments must be evaluated into a value of the same type. Hence, the result could be either a Guid
, or an int
. The (inferred type)
would then be this type. However, the ??
cannot convert the values of Guid
and int
operands into a value of such a single type.
Note: You could argue that the compiler could choose object
as the closes type compatible with both Guid
and int
and just box those values into an object. However, that would undermine the very sense of strong type checking. It would be just 'too relaxed'.
In your particular example, sticking with ??
seems artificial; a good old ?:
and a little bit more expressiveness in your code would do better and maybe even help readability:
var parameters = new Parameters()
{
new Parameter("id", FKGuid.HasValue ? ToTypeParameterExpects(FKGuid.Value) : ToTypeParameterExpects(id))
};
Obviously, the ToTypeParameterExpects
is a conversion to whatever type the Parameter
's constructor expects for the value.