2010-10-23 60 views
10

我想创建一个简单的方法,它接受值类型参考类型参数,即int是值,string是参考。正在创建一个接受(可为空)值类型和引用类型的C#泛型方法吗?

原来这就是我开始:

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 

但我遇到的第一个问题是

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'

要继续,我添加一个结构约束我的方法

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

但现在的方法将不接受基于字符串的呼叫,并给了我这个错误:

The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method.

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

+1

这似乎是一件奇怪的事情要做? – 2010-10-23 08:07:10

+5

这并不奇怪,它只是一种C++的甜味。 – 2010-10-23 08:09:45

回答

22

你的问题是,你想要的是相互冲突的泛型类型的限制:

  • 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!而非。

+0

我还会在T:struct和where T:方法中添加类约束。 – 2010-10-23 08:44:20

+1

对不起,这是一个复制/粘贴错误行r3,我会更新的问题,“三”,“四”应该是参数。 – 2010-10-23 10:44:00

+0

@Sara:关于理解Nullable ,我写了一篇关于它的博客文章:http://softwareblog.alcedo.com/post/2010/02/16/Nullable3cT3e-vs-null.aspx – 2010-10-23 13:45:08

相关问题