接线员'??' 不能应用于'T'和'T'类型的操作数

Kri*_*ave 54 c# generics compiler-errors

我有以下通用方法,但VS给我一个编译错误.(运算符'??'不能应用于'T'和'T'类型的操作数

public static T Method<T>(T model) where T : new()
{
    var m = model ?? new T();
}
Run Code Online (Sandbox Code Playgroud)

有人知道为什么吗?

编辑:可能的原因是T在我的情况下可以是一个结构,并且结构是一个非可空类型?

mpe*_*pen 84

??是空合并运算符.它不能应用于非可空类型.既然T可以是任何东西,它可以是一种int或其他原始的,不可空的类型.

如果添加条件where T : class(必须在之前指定new()),则强制它T成为可以为空的类实例.

  • @KristofDegrave没有新的()只意味着会有一个空的construtor (3认同)
  • +1完整答案伤心它不是带勾的那个 (2认同)

Kav*_*ian 58

你应该添加class约束:

public static T Method<T>(T model) where T : class, new()
{
    var m = model ?? new T();

    return m;
}
Run Code Online (Sandbox Code Playgroud)

你也应该回来m!

注意:正如@KristofDegrave在他的评论中提到的那样,我们必须添加class约束的原因是因为T可以是一个值类型,int因为??运算符(null-coalescing)检查可以为null的类型,所以我们必须添加class约束排除值类型.

编辑:Alvin Wong的回答也涵盖了可空类型的案例; 实际上是结构,但可以是??的操作数?运营商.请注意,Method如果null没有Alvin的重载版本,将返回可为空的类型.

  • @KristofDegrave你是对的.这就是我们必须在这里明确添加`class`约束的原因. (4认同)
  • 可能的原因是T在我的情况下可以是结构,并且结构是不可为空的类型吗? (3认同)
  • 我想两个都给他们,但这是不可能的.两者都给出了我的问题的答案,但这是我的评论得到答案的唯一答案,这就是为什么 (3认同)
  • 当然他们是一样的!但在问题中,第一个被使用.这只是我提到过的. (2认同)

Alv*_*ong 32

许多人已经指出,class为泛型添加约束将解决问题.

如果您希望您的方法也适用Nullable<T>,您可以为它添加一个重载:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

  • @KristofDegrave只是指出完整性.别人可能需要它!:) (10认同)

Bid*_*dou 8

您需要指定您的T类型是具有泛型类型约束的类:

public static T Method<T>(T model) where T : class, new()
{
    return model ?? new T();
}
Run Code Online (Sandbox Code Playgroud)