我目前对于在值和/或引用类型上检查'null'(空,不可用,没有值)时有点困惑。似乎有很多可能的方法,并且经常使用它们。
假设我有以下扩展方法,可以某种方式类似于monad:
public static TResult UseWith<T, TResult>(this T value, Func<T, TResult> action)
{
// if value not null
// execute action
// else return the default value of 'TResult'
}
所以?我如何检查空?
if(value != null)
或(它在引用类型上检查null,但在值类型上默认检查)
if(!Equals(value, default(T))
或
if(!EqualityComparer<T>.Default.Equals(value, default(T))
或(预先检查)
if (!typeof(T).IsValueType)
{
if (Equals(source, default(T)))
return TResult;
}
或者创建两个有限制的方法更好吗?
public static TResult UseWith<T, TResult>(this T value, Func<T, TResult> action)
where T : class
{
if(value == null)
public static TResult UseWith<T, TResult>(this T value, Func<T, TResult> action)
where T : struct
{
if(value.HasValue)
答案 0 :(得分:2)
您的第一个代码段中的伪代码将完全按照您的意愿工作。可以使用null
运算符将键入为无界泛型参数的变量与==
进行比较。代码将进行编译,只要false
为非可空值类型,它就会简单地计算为T
。
您不希望将T
与默认值进行比较,因为默认值可能不是null
。
没有必要显式检查T
是否为值类型,或者对引用/值类型具有单独的重载,因为==
运算符在JITted时处理它。