如何“泛化”这种扩展方法?

时间:2011-03-31 16:44:02

标签: c# generics c#-3.0 extension-methods

我有以下适用于int的方法吗?变量。我想将它扩展到任何数字可空变量(例如十进制?,双?等等)

public static bool IsNullOrInvalid(this System.Nullable<int> source)
{
    return (source == null || source == -1);
}

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:8)

棘手的一点就是找出每种情况下“无效”的含义。如果“任何被认为低于数据类型默认值的值”是可以的,您可以尝试:

public static bool IsNullOrNegative<T>(this T? source)
    where T : struct, IComparable<T>
{
    return source == null || source.Value.CompareTo(default(T)) < 0;
}

编辑:如评论中所述,没有“数字”约束 - 在与自身相当的每种值类型上调用此方法都是有效的,例如DateTime。没有办法避免这种情况 - 添加更多约束可能会略微降低设置,但不会完全降低。

至于与-1完全比较,你需要能够为每种类型计算出值“-1”。没有通用的方法。您可以手动为我感兴趣的每种类型构建一个“{1}}”-1,但这将非常难看。

如果-1无效,-2是否真的有效?这对我来说似乎很奇怪。

答案 1 :(得分:0)

我不认为这是可能的,因为要使这种通用,它必须是所有类型的通用,而无效是特定于整数。如果只是对该方法进行重载(double,float等),编译器应该在键入时找出你想要的那个

(0.0).IsNullOrValid()

答案 2 :(得分:0)

你不能,为了做到这一点,你需要

public static bool IsNullOrInvalid<T>(this System.Nullable<T> source) where T : Numeric

但c#中的数字没有Numeric基类 问题是source == -1,没有适用于-1的公共类或接口。

你可以突破-1

public static bool IsNullOrInvalid<T>(this System.Nullable<T> source, T invalid)
    where T: struct, IEquatable<T>
{
    return (source == null || source.Value.Equals(invalid));
}

但是你需要像这样打电话

int? foo = -1;
var isInvalid = foo.IsNullOrInvalid(-1);