AngryHacker
AngryHacker

Reputation: 61596

How to "genericize" this extension method?

I have the following method that currently works on int? variables. I'd like to extend it to any numeric nullable variables (e.g. decimal?, double?, etc...)

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

How can I pull this off?

Upvotes: 0

Views: 194

Answers (3)

Albin Sunnanbo
Albin Sunnanbo

Reputation: 47038

You can not, to make that possible you would need

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

but there is no Numeric base class for numbers in c#.
The problem is source == -1, there is no common class or interface that works with -1.

you could break out the -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));
}

But then you need to call like this

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

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499800

The tricky bit is working out what "invalid" means in each case. If "any value which is deemed less than the default for the data type" is okay, you could try:

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

EDIT: As noted in comments, there's no "numeric" constraint - it will be valid to call this method on every value type which is comparable with itself, such as DateTime. There's no way of avoiding that - adding more constraints would probably reduce the set slightly, but not completely.

As for comparing with exactly -1, you'd need to be able to work out the value "-1" for every type. There's no generic way of doing that. You could manually build a Dictionary<Type, object> of "-1 for each type I'm interested in" but it would be pretty ugly.

If -1 is invalid, is -2 really valid? That seems odd to me.

Upvotes: 8

poindexter12
poindexter12

Reputation: 1783

I don't think this is possible because to make this generic, it has to be generic across all types and invalid is specific to the integer. If you just make overloads of that method (double, float, etc.), the compiler should figure out which one you want when you type

(0.0).IsNullOrValid()

Upvotes: 0

Related Questions