泛型函数:返回一个非空值
本文关键字:一个 空值 函数 返回 泛型 | 更新日期: 2023-09-27 18:06:20
我写了这个简单的实用函数:
public static T isNull<T>(T? v, T d)
{
return v == null ? d : v.Value;
}
的目的是避免恼人的任务,如检查成员是否为空,这在读取linq记录集时非常常见。问题是它抛出了这个错误:
类型'T'必须是一个非空值类型,以便在泛型类型或方法'System.Nullable
的
这个错误似乎是合法的,无论如何我希望我能做这样的事情:
int? myField = record.myField;
int myValue = isNull(myField, 0);
代替:
int? myField = record.myField;
int myValue = myField == null ? 0 : myField.Value;
我觉得我遗漏了一些c#的基本知识。是否存在一种方法来完成我的任务?
泛型约束可以用于泛型函数,以限制允许用于特定子集的类型,这为您如何在方法或类中使用这些类型提供了可能性。
在这种情况下,您可以对T
应用约束,将其限制为struct
,以解决特定的编译器错误。
public static T IsNull<T>(T? v, T d) where T : struct
{
return v == null ? d : v.Value;
}
然而,另一个答案确实正确地指出,在这种特定的情况下,您可以选择使用空合并运算符??
。 这被称为空合并,并且有一个内置的操作符来完成它:
int myValue = record.myField ?? 0
虽然其他答案都很好,但您可能希望编写的方法可以同时使用引用和值类型。您可以通过两个重载来实现这一点,这两个重载都带有泛型约束。
public static T IsNull<T>(T v, T d) where T : class
{
return v ?? d;
}
public static T IsNull<T>(T? v, T d) where T : struct
{
return v.HasValue ? v.Value : d;
}
注意:用Nullable<T>
以外的值类型调用IsNull
仍然不会编译。例如
string myString = ...
Console.WriteLine(IsNull(myString, "foo")) // works
object myObject = ...
Console.WriteLine(IsNull(myMyObject, new object())) // works
DateTime? myDateTime = ...
Console.WriteLine(IsNull(myDateTme, DateTme.Now)) // works
int? myInt1 = ...
Console.WriteLine(IsNull(myInt1, DateTme.Now)) // works
int myInt2 = ...
Console.WriteLine(IsNull(myInt2, DateTme.Now)) // <-- compiler error