Operator '??' cannot be applied to operand

2019-03-17 02:42发布

问题:

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?

回答1:

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.



回答2:

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



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


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


回答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.



回答6:

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


回答7:

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.



回答8:

Mark T as "class" and you are good to go.