c# - 一般检查不会在非约束类型上装箱可空值的 null。

标签 c# generics

假设我有以下方法:

public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
{
    if (enumerable == null) throw new ArgumentNullException("enumerable");
    int count = 0;
    foreach (var x in enumerable)
    {
        if (x != null) count++; 
    }
    return count;
}

我有这 3 个数组::

var ints = Enumerable.Range(0,10).ToArray();
var nullableInts = Array.ConvertAll(ints,x=>x as int?);
var strings = Array.ConvertAll(ints,x => x.ToString());

我写了一个小函数来做一个循环并为它计时一百万次迭代。将其应用于 intsstrings ,它在我的机器上大约在 100 毫秒内完成。对于 nullableInts ,需要 2.5 秒。 据我了解,检查 int 是否为空没有意义,所以编译器有一个不同的非空模板 struct类型,删除空检查。但是Nullable<T>没有将空检查转换为 x.HasValue 的模板.如果我有一个不受约束的函数,我怎样才能进行性能良好的空值检查?我不能使用 EqualityComparer<T> ,因为 null 可能不是 T 的成员因为没有约束。

此外,不可能有因约束而异的重载,所以我不能,比如说,为 structs 设置一个重载。 , 一个用于 Nullable<T> ,还有一个用于类(class)。

方法的调用者是不受约束的。这只是一个例子(不是实际的方法);方法调用是不受约束的。我需要对非空成员做一些工作,这是一种通用方法。我想我可以编写一个不进行检查的版本与一个进行检查的版本(因此具有不同的签名),但它看起来非常丑陋且不需要。

另外,扩展方法.Count莫名其妙地为 NullableInts 表现得很糟糕和 strings ,(同样糟糕),所以这确实不是正确的方法。这可能是委托(delegate)调用,但我对此表示怀疑。使用 UnboxT Check<T>.IfNull的样式方法表现好多了。 好吧,真的很奇怪,将 count 的主体切换到这个执行得很好:

    public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
    {
        return enumerable.Count(Check<T>.IfNull.Invoke);
    }

为什么?

最佳答案

您可以 constrain generic type parameters引用类型或值类型:

public static int CountNonNull<T>(this IEnumerable<T> source)
    where T : class
{
    return source.Count(x => x != null);
}

public static int CountNonNull<T>(this IEnumerable<Nullable<T>> source)
    where T : struct
{
    return source.Count(x => x.HasValue);
}

对于不可为 null 的结构不需要重载,因为它们无论如何都不能为 null。

关于c# - 一般检查不会在非约束类型上装箱可空值的 null。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3999761/

相关文章:

Python 键入 : how to get Type[C] to work with TypeVars and Generics?

c# - 如何在您的 Asp.net 应用程序中获取最新的货币汇率

java - 我还必须做什么才能让我的方法处理任何类型的对象

java - 二叉搜索树实现中迭代器和泛型的困难

c#无限计算器,显示所有数字

generics - Swift 泛型和相关类型的错误

c# - 为什么 C# 编译器不自动推断此代码中的类型?

c# - Log4Net : "Could not load file or assembly ' log4net, 错误 Version=1.2.10.0,Culture=neutral,PublicKeyToken=null' 或其依赖项之一”

c# - .NET 单任务等待的用例

c# - 在 C# 中使用通用存储库时连接多个表