是否可以创建一个接受(可空)值类型和引用类型的C#泛型方法?

时间:2010-10-23 07:56:25

标签: c# .net generics value-type reference-type

我想创建一个接受值类型引用类型参数的简单方法,即int是value,string是reference。

所以这就是我的开始:

public bool areBothNotNull<T>(T? p1, T? p2)
{
    return (p1.HasValue && p2.HasValue);
}

所以我希望能够像这样使用它:

var r1 = areBothNotNull<int>(3, 4); // will be true
var r2 = areBothNotNull<int>(3, null); // will be false
var r3 = areBothNotNull<string>("three", "four"); // will be true
var r4 = areBothNotNull<string>(null, "four"); // will be false

但我遇到的第一个问题是

类型'T'必须是非可空值类型才能在泛型类型或方法'System.Nullable'中将其用作参数'T'

为了继续,我将一个结构约束添加到我的方法

public bool areBothNotNull<T>(T? p1, T? p2) where T : struct

但是现在该方法不接受基于字符串的调用,并且给出了这个错误:

类型'string'必须是非可空值类型,以便在泛型类型或方法中将其用作参数'T'。

这可能吗?或者为什么我们阻止这样做?

1 个答案:

答案 0 :(得分:23)

您的问题是您需要彼此冲突的泛型类型约束:

  • Nullable<T>仅适用于值类型
  • 参考类型不是值类型

因此,您需要有两个重载才能使代码正常工作:

public static bool areBothNotNull<T>(T? p1, T? p2) where T : struct
{            
    return (p1.HasValue && p2.HasValue);
}

public static bool areBothNotNull<T>(T p1, T p2)
{
    return (p1 != null && p2 != null);
}

但是,以下行永远不会编译:

var r3 = areBothNotNull<string>(3, 4);

这里存在冲突,泛型类型参数声明参数类型为string,但代码尝试传递int