在C#中,给定两个输入Type
,可以为运算符确定输出Type
和隐式向上Type
吗?例如,考虑表达式s + i
。说我有以下信息:
short s;
int i;
Type leftType = typeof(short);
Type rightType = typeof(int);
我可以确定有关表达式s + i
的以下信息吗?
Type leftUpcastType = typeof(int);
Type rightUpcastType = typeof(int);
Type outputType = typeof(int);
我显然可以使用所有类型和运算符的巨大查找表来完成此操作,但可能有一种更简单的方法。理想情况下,这也适用于具有运算符重载的用户定义类,但这是次要要求。
答案 0 :(得分:2)
是的,您可以使用dynamic
类型实现此目的。但请记住,动态会为无法在运行时总结的任何内容抛出异常,因此您需要确保只传递有效值或包装在try /中捉。
var leftType = left.GetType();
var rightType = right.GetType();
var outputType = ((dynamic)left + (dynamic)right).GetType();
然后,您可以根据此信息推断是否为对象操作转换了一个,两个或两个对象。
答案 1 :(得分:2)
执行此操作的最佳方法是检查表达式的返回类型,该表达式添加了您感兴趣的类型的两个值。这样您就不必担心提供有效的值在运行时添加,当你关心的只是返回类型。
您可以使用现有表达式并在表达式树中向下走(如果有的话),或者执行以下操作:
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
}
此泛型方法将返回添加操作的类型,而不实际执行添加。
当然,您可以使用Type
个实例而不是通用类型参数执行此操作,如果这是您想要的:
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;
}
要明确指出,DynamicExpression
来自System.Linq.Dynamic
命名空间,您可以通过引用来获取:https://www.nuget.org/packages/System.Linq.Dynamic/