Reputation: 2328
If I have a generic function that returns a T
or some default value I want to use the ??
operator
T f<T>(T a, T b)
{
return a ?? b;
}
This fails with the message
Operator '??' cannot be applied to operands of type 'T' and 'T'
I assume this is because T
might not be nullable. But I would also assume that the ??
operator above should do the same as
T f<T>(T a, T b)
{
var a_ = a;
return a_ != null ? a_ : b;
}
And the second code compiles without a problem.
So why are those cases handled differently even though they should do the same?
Upvotes: 5
Views: 167
Reputation: 42225
From this question on dotnet/csharplang:
The reason for this is that ?? is intended to unwrap the type on the left if the type on hte left is
Nullable<T>
. In other words, today i can write:int? x ...; int y ...; int z = x ?? y;
So, it's not the case that "x ?? y" translates to "x != null ? x : y". It can translate to "x != null ? x.Value : y".
Since we don't know if T is a value or reference type, we cannot effectively do the transformation. However, when T is constrained to "class" or "struct" (and in the latter case, is a T?), then we can do the transformation.
See the rest of that thread for a wider discussion.
There's a discussion around relaxing this.
Upvotes: 5
Reputation: 499
What is T struct or class? Thats why it cant return default type.
T fa<T>(T a, T b)where T :class
{
return a ?? b;
}
Upvotes: -1
Reputation: 535
Not every object is nullable... Classes are nullable. Therefore, you have to indicate that what you are passing in is a class. Alternatively, use default(T)
instead of null
, but if you pass in 'int' for T, that will be zero instead of null
.
T f<T>(T a, T b)
where T: class
{
....
}
Upvotes: 0