Matthew Holmes
Matthew Holmes

Reputation: 803

Casting generic type to its non-nullable form

I have the following method

public ValidationOutput PerformMatch<T>(IEnumerable<T> values, decimal maximum)

values can beInt32? Int64? or decimal?. All elements of values for a call of this method will be one of these types, but we don't know which they will all be in advance.

I need to check if each element of Values is null, if not, cast them to the non-nullable versions, so that I can then do comparisons against maximum which is always a decimal.

That is I would ToList() values and then do something like

if(Math.Abs((Int32)Values[i]-(Int32)Values[i+1])) < maximum)
{
}

My question is how can I do this casting with generic types? If it can't be done then is my only option to have 3 PerformMatch methods that have almost duplicated code?

Edit: The main issue I have is Math.Abs requires a non-nullable type. I am having difficulty casting a generic type to a non-nullable type

Upvotes: 0

Views: 1678

Answers (4)

seesharpconcepts
seesharpconcepts

Reputation: 180

If I understand correctly you would like to list of all items in values which are not null.

var list = values.Where(x=>x.HasValue).ToList();    

HasValue checks if item has value and is not null.

Upvotes: 1

Heinzi
Heinzi

Reputation: 172220

If you only have three types, I would suggest not to use generics here:

public ValidationOutput PerformMatch(IEnumerable<Int32?> values, decimal maximum)
{
    return PerformMatch(values.Select(i => (decimal?)i), maximum);
}

public ValidationOutput PerformMatch(IEnumerable<Int64?> values, decimal maximum)
{
    return PerformMatch(values.Select(i => (decimal?)i), maximum);
}

public ValidationOutput PerformMatch(IEnumerable<decimal?> values, decimal maximum)
{
    // your logic here
}

Upvotes: 1

phoog
phoog

Reputation: 43046

Try

public ValidationOutput PerformMatch<T>(IEnumerable<T?> values, decimal maximum)
where T : struct

Then you can use the HasValue property and the GetValueOrDefault method to do what you want.

Upvotes: 3

Euphoric
Euphoric

Reputation: 12849

First, add Nullable to the definition of the type:

public ValidationOutput PerformMatch<T>(IEnumerable<Nullable<T>> values, decimal maximum)

Then, you can access the nullability information without a problem. After that, simply use Convert.ToDecimal method to get the decimal value.

if(Values[i].HasValue)
{
    T val = Values[i].Value;
    decimal valDec = Convert.ToDecimal(val);
    // do whatever.
}

Upvotes: 4

Related Questions