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

前端 未结 8 713
旧巷少年郎
旧巷少年郎 2021-02-06 20:34

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         


        
相关标签:
8条回答
  • 2021-02-06 21:06

    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.

    0 讨论(0)
  • 2021-02-06 21:09

    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;
    }
    
    0 讨论(0)
  • 2021-02-06 21:13

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

    0 讨论(0)
  • 2021-02-06 21:14

    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.

    0 讨论(0)
  • 2021-02-06 21:16

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

    0 讨论(0)
  • 2021-02-06 21:19

    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);
    }
    
    0 讨论(0)
提交回复
热议问题