I have a generic method dealing with large amounts of data of various types.
I'd like to apply some additional processing when the data is a specific type (double
in this case). All other functionality is identical across the different types.
Is there a better way than the (very slow) box/unboxing illustrated in the example below?
This seems to imply that we need to convince the compiler that T
and double
are the same type, within the if..else
section that asserts this.
public static T[] HalfIfDouble<T>(T[] data)
{
T[] result;
if (typeof(T) == typeof(double))
{
// result = data.Select(x => x * 0.5).ToArray(); // does not compile
result = data.Select(x =>
{
double d = (double)(object)x;
return (T)(object)(d * 0.5);
}).ToArray();
}
else
{
result = data;
}
// do some more processing...
return result;
}
The real functionality is obviously more complicated than this example.
Needs to work in .NET Framework and .NET 6.
CodePudding user response:
You can use the as
operator to do the casting rather than (T)
.
- In the expression
value as T
it will attempt to castvalue
to the typeT
if it's possible, otherwise the value will benull
. as
is only available when casting to a reference type (in your case an array).
You can also use the is
operator to replace the type check.
- In the expression
value is T
the expression will be true ifvalue
can be cast to the typeT
. - In the expression
value as T tValue
the expression will be true ifvalue
can be cast to the typeT
and the variabletValue
will be assigned the value of(T)value
.
Updating your code with these operators we get:
- If in .Net Framework or in .Net and nullable reference types are disabled:
public static T[] HalfIfDouble<T>(T[] data)
{
T[] result;
if (data is double[] da)
{
result = da.Select(x => x * 0.5).ToArray() as T[];
}
else
{
result = data;
}
// do some more processing...
return result;
}
- If in .Net and nullable reference types are enabled:
- This uses the null-forgiving operator
!
to to tell the compiler thatas T[]
will never returnnull
.- When nullable reference types are enabled
as T[]
results inT[]?
because if the cast fails the result isnull
. - We know that it won't result in
null
because we knowT
is adouble
fromdata is double[]
so we can safely use this.
- When nullable reference types are enabled
public static T[] HalfIfDouble<T>(T[] data)
{
T[] result;
if (data is double[] da)
{
result = (da.Select(x => x * 0.5).ToArray() as T[])!;
}
else
{
result = data;
}
// do some more processing...
return result;
}