C#泛型以避免代码重复?

C#泛型以避免代码重复?,c#,generics,primitive-types,C#,Generics,Primitive Types,我对来自Java的C#相当陌生,我想知道是否有一种简单的方法可以避免涉及以下基本类型的代码重复: private Boolean AtLeastOneBufferItemIsNonZero(int[] Buffer) { Boolean result = false; foreach (int Item in Buffer) { result = !(Item == (int)0); if (result) break; }

我对来自Java的C#相当陌生,我想知道是否有一种简单的方法可以避免涉及以下基本类型的代码重复:


private Boolean AtLeastOneBufferItemIsNonZero(int[] Buffer)
{
    Boolean result = false;
    foreach (int Item in Buffer)
    {
        result = !(Item == (int)0);
        if (result) break;
    }
    return result;
}

private Boolean AtLeastOneBufferItemIsNonZero(float[] Buffer)
{
    Boolean result = false;
    foreach (float Item in Buffer)
    {
       result = !(Item == (float)0);
       if (result) break;
    }
    return result;
}
我找不到“Number”超类型,因此我无法在泛型实现中比较“Item”(我不介意装箱的性能损失,尽管我知道在.NET中没有这样的东西):


//像这样的?
私有布尔值AtLeastOneBufferItemIsNonZero(T[]缓冲区),其中T:NUMBERTYPE
{
布尔结果=假;
foreach(缓冲区中的T项)
{
结果=!(Item.Equals(0));//否。。。。
如果(结果)中断;
}
返回结果;
}

是创建自己的数字实现并拥有compare()方法的唯一方法吗?这听起来有点过分了,不是吗?

LINQ通过依赖任何数字类型的默认值为零,并且它们有适当的相等方法,使得这一点非常简单:

private bool AtLeastOneBufferItemIsNonZero<T>(T[] items)
{
    T zero = default(T);
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    return items.Any(t => !comparer.Equals(t, zero));
}
但这在我看来有点毫无意义。更改为使用
EqualityComparer.Default
,您还可以使用该方法检查引用类型序列中的任何值是否为非null

编辑:作为旁注,另一种看待它的方式是反转条件:

return !items.All(t => comparer.Equals(t, zero));
这取决于你对“它们中的任何一个都不是零”或“它们不全是零”的概念是否感到满意:

private Boolean AtLeastOneBufferItemIsNonZero(T[]Buffer)
{
布尔结果=假;
foreach(缓冲区中的T项)
{
结果=!Item.Equals(默认值(T));//是!!!
如果(结果)中断;
}
返回结果;
}

注:使用Linq有一些类似的问题。检查他们是否帮助你。两个示例:在旁注中,使用
bool
而不是
Boolean
。bool是一个快捷方式。但它返回一个值,指示是否至少有一个项为零?但不应该将其命名为
AtLeastOneBufferItemIsZero
?@Jim:是的,因此Fredrik发表了评论。修正:)@Stuart:那不行;你不能申请使用泛型类型参数,除非它被约束为类类型。谢谢大家的帮助。我会尽快看一看LINQ
public static class Extensions
{
    public static bool ContainsNonDefaultValue<T>(this IEnumerable<T> source)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        T zero = default(T);
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        return items.Any(t => !comparer.Equals(t, zero));
    }
}
where T : struct
return !items.All(t => comparer.Equals(t, zero));
private Boolean AtLeastOneBufferItemIsNonZero<T>(T[] Buffer)
{
    Boolean result = false;
    foreach (T Item in Buffer)
    {
       result = !Item.Equals(default(T)); //Yep!!!
       if (result) break;
    }
    return result;
}