I have the following generic method, but VS gives me a compile error on that. (Operator \'??\' cannot be applied to operands of type \'T\' and \'T\')
public stat
model ?? new T()
means model == null ? new T() : model
. It is not guaranteed that model is non-nullable and ==
cannot be applied for null
and a non-nullable object. Changing constraint to where T : class, new()
should work.
For some reason the ??
operator can't be used on non-nullable types, even though it is supposed to be equivalent to model == null ? new T() : model
, and you are allowed a null comparison with a non-nullable type.
You can get exactly what you're looking for without any additional constraints by using the ternary operator instead, or an if statement:
public static T Method<T>(T model) where T : new()
{
var m = model == null ? new T() : model;
}
Mark T as "class" and you are good to go.
You should add class
constraint:
public static T Method<T>(T model) where T : class, new()
{
var m = model ?? new T();
return m;
}
And you should return m
too!
Note: As @KristofDegrave mentioned in his comment, the reason that we have to add class
constraint is because T can be a value type, like int
and since ??
operator (null-coalescing) check on types that can be null, so we have to add class
constraint to exclude value types.
Edit: Alvin Wong's answer covered the case for nullable types too; which are structs actually, but can be operands of ?? operator. Just be aware that Method
would return null
without Alvin's overloaded version, for nullable types.
??
is the null-coalescing operator. It can't be applied to non-nullable types. Since T
can be anything, it can be an int
or other primitive, non-nullable type.
If you add the condition where T : class (must be specified before new()
) it forces T
to be a class instance, which is nullable.
Many have pointed out already that adding the class
constraint for the generic will solve the problem.
If you want your method to be applicable to Nullable<T>
too, you can add an overload for it:
// For reference types
public static T Method<T>(T model) where T : class, new()
{
return model ?? new T();
}
// For Nullable<T>
public static T Method<T>(T? model) where T : struct
{
return model ?? new T(); // OR
return model ?? default(T);
}