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

Solution 1:

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

Solution 2:

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.

Solution 3:

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);
}

Solution 4:

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();
}

Solution 5:

Since T can be any type, there is no guarantee that T will have a static ?? operator or that the type T is nullable.

?? Operator (C# Reference)

The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types.