4

where T : struct约束仅允许将可接受类型参数的域限制为一组值类型(与包括值类型和引用类型的类型的超集相比),但似乎也完全禁止可空类型,尽管可空并不一定意味着现代版本的 C# 中的引用类型。

如果我想接受具有附加可空性的值类型(例如int?等)DateTime?同时拒绝原生可空引用类型(例如字符串、IList 等)怎么办?是否可以以这种方式定义约束?如果是怎么办?

我真的很想学习实现这两种场景:当用作参数的类型必须既是值又是可空的,以及当一个可空的值类型和不可为空的值类型一样被接受时,我认为这些相关足够接近以原谅提及这两种情况,所以我很感激对第二种情况的谦虚评论,并选择一个答案,包括它作为一个更好的答案(假设另一个答案在其他方面不会真的更好)如果多个答案将是提交,我必须选择,但我现在真正需要的是第一种情况(总是需要一个既可以为空又是值类型的类型),我也相信第二种情况会考虑到第一个知识,非常简单,更不用说坚持将 2 个问题合二为一不是一种好方法,所以我绝对会感激并接受仅处理第一个案例的答案。

4

2 回答 2

6

你不能。Nullable<T>不是 C# 中泛型的有效约束。

当您尝试类似的操作class X<T,U> where T : Nullable<U>时,会出现以下错误:

“你?” 不是有效的约束。用作约束的类型必须是接口、非密封类或类型参数。

如果您需要同时接受TNullable<T>作为方法参数,您可以提供覆盖:

class X<T>  where T : struct
{
   public void R(T arg){ Console.WriteLine("Non nullable: {0}", arg);}
   public void R(Nullable<T> arg){Console.WriteLine("Nullable: {0}", arg);}
}

然后你可以调用任一版本:

X<int> r = new X<int>();
r.R((int?)4);
r.R(4);

在您的类型中只处理Nullable值,您可以简单地约束T:struct但在类中的任何地方都使用Nullable<T>参数和字段。

关于特定方面的更多讨论 - C# 泛型类型约束,适用于所有可为空的和相关问题。

于 2017-03-26T03:11:10.490 回答
5

这不是想要的,但也许您可以使用 IConvertible 的类型约束?作为一个接口,它可以为空,由 Boolean、SByte、Byte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Decimal、DateTime、Char 和 String 实现。

class MyClass<T> where T : IConvertible
{
    //Etc
}
于 2017-03-26T03:13:40.337 回答