ChatGPT解决这个技术问题 Extra ChatGPT

帮助解决 C# 泛型错误 - “类型 'T' 必须是不可为空的值类型”

我是 C# 新手,不明白为什么下面的代码不起作用。

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable
{
    if (a.HasValue && b.HasValue)
        return a.Value.CompareTo(b.Value) < 0 ? b : a;
    else if (a.HasValue)
        return a;
    else
        return b;
}

// Sample usage:
public DateTime? CalculateDate(DataRow row)
{
    DateTime? result = null;
    if (!(row["EXPIRATION_DATE"] is DBNull))
        result = DateTime.Parse((string)row["EXPIRATION_DATE"]);
    if (!(row["SHIPPING_DATE"] is DBNull))
        result = CoalesceMax(
            result
            DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1));
    // etc.
    return result;
}

它在编译期间给出以下错误:

类型“T”必须是不可为空的值类型,才能将其用作泛型类型或方法“System.Nullable”中的参数“T”

编译器错误为您提供了函数定义的行,因为那是错误所在。

L
Liam

您需要添加一个 T : struct 约束:

public static Nullable<T> CoalesceMax<T>
    (Nullable<T> a, Nullable<T> b) where T : struct, IComparable

否则 C# 将尝试找出 Nullable<T> 的含义,并意识到它还没有 Nullable<T> 本身所需的约束。换句话说,您可以尝试调用:

CoalesceMax<string>(...)

这没有意义,因为 Nullable<string> 无效。


C# 8 Not nullable flag 怎么样?
@kirinnee:不,因为 Nullable<T> 仍然需要 T 是不可为空的值类型,而不仅仅是任何不可为空的类型。
佚名

Nullable<T> 类型有一个约束,要求 T 是值类型(C# 中的 struct)。这就是为什么编译器会告诉您有关 Nullable<T> 而不是您的函数或该函数的调用站点的原因 - 它是 Nullable 类是错误的根本原因,所以这实际上更有帮助,如果编译器只是指着你的功能说“这不对,修复它!” (想象一下,如果 CoalesceMax 使用了几个泛型,并且只违反了其中一个的约束 - 知道哪个泛型的约束被破坏比只知道 CoalesceMax 中的一个或多个约束被破坏更有用)。

解决方案是通过引入相同的约束来使您的 T 和它们的 T 兼容。这是通过添加 struct 约束来完成的,该约束必须位于所有接口/新约束之前:

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
  ...
}

S
SLaks

您的通用方法正在使用 Nullable<T>

但是,您没有限制 T 的类型,因此它最终可能是 Nullable<Form>,这显然是无效的。

您需要将约束更改为 where T : struct, IComparable 以确保 T 只能是值类型。


3
3-14159265358979323846264

不完全是对 OP 的回答,但由于这是在谷歌上弹出相同错误消息的第一件事,我不得不在我的类定义上添加约束,而不是我的方法,例如

public class MyClass<T> where T : struct
{
    public void MyMethod(T? value)
    {
    }
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅