Reputation: 6041
In C#, given two input Type
s, it it possible to determine the output Type
and implicit upcast Type
s for an operator? For example, consider the expression s + i
. Say I have the following information:
short s;
int i;
Type leftType = typeof(short);
Type rightType = typeof(int);
Can I determine the following information about the expression s + i
?
Type leftUpcastType = typeof(int);
Type rightUpcastType = typeof(int);
Type outputType = typeof(int);
I obviously could do this with an enormous lookup table of all the types and operators, but there might be an easier way. Ideally this would work for user-defined classes with operator overloads too, but that is a secondary requirement.
Upvotes: 3
Views: 158
Reputation:
The best way to do this is to examine the return type of an expression that adds two values of the types you're interested in. This way you don't need to worry about providing valid values for the addition at runtime, when all you care about is the return type.
You can either take an existing expression and walk down the expression tree if one is available to you, or do something like this:
static Type GetTypeOfSummation<T1, T2>()
{
var p1 = Expression.Parameter(typeof(T1), "t1");
var p2 = Expression.Parameter(typeof(T2), "t2");
LambdaExpression x = DynamicExpression.ParseLambda(new[] { p1, p2 }, null, "t1 + t2");
return x.Body.Type;
}
static void Main()
{
Console.WriteLine(GetTypeOfSummation<int, double>()); // System.Double
Console.WriteLine(GetTypeOfSummation<int, decimal>()); // System.Decimal
Console.WriteLine(GetTypeOfSummation<float, double>()); // System.Double
}
This generic method will return the type of the addition operation without actually performing the addition.
You can of course do this with Type
instances instead of generic type parameters as well, if that's what you want:
static Type GetTypeOfSummation(Type t1, Type t2)
{
var p1 = Expression.Parameter(t1, "t1");
var p2 = Expression.Parameter(t2, "t2");
LambdaExpression x = DynamicExpression.ParseLambda(new[] { p1, p2 }, null, "t1 + t2");
return x.Body.Type;
}
To be clear, DynamicExpression
is from the System.Linq.Dynamic
namespace, which you can obtain by referencing: https://www.nuget.org/packages/System.Linq.Dynamic/
Upvotes: 2
Reputation: 3256
Yes, you can achieve this using the dynamic
Type. Keep in mind, though, that dynamic will throw an exception for anything that can't be summed at runtime so you will need to ensure that you are only passing valid values or wrap in a try/catch.
var leftType = left.GetType();
var rightType = right.GetType();
var outputType = ((dynamic)left + (dynamic)right).GetType();
You can then infer from this information whether one, both or neither of the objects were converted for the operation.
Upvotes: 2