Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator '??' cannot be applied to operands of type 'T' and 'T'

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 static T Method<T>(T model) where T : new()
{
    var m = model ?? new T();
}

Does some one have any idea why?

Edit: Is it possible the reason is that T can be a struct in my case, and a struct is an non-nullable type?

like image 763
Kristof Degrave Avatar asked Jun 13 '13 06:06

Kristof Degrave


4 Answers

?? 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.

like image 68
mpen Avatar answered Oct 14 '22 19:10

mpen


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.

like image 43
Kaveh Shahbazian Avatar answered Oct 14 '22 20:10

Kaveh Shahbazian


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);
}
like image 32
Alvin Wong Avatar answered Oct 14 '22 20:10

Alvin Wong


You need to specify that your T type is a class with a constraint on the generic type:

public static T Method<T>(T model) where T : class, new()
{
    return model ?? new T();
}
like image 8
Bidou Avatar answered Oct 14 '22 19:10

Bidou