以编程方式获取转换和输出运算符的类型

时间:2015-05-12 20:05:41

标签: c# reflection casting

在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);

我显然可以使用所有类型和运算符的巨大查找表来完成此操作,但可能有一种更简单的方法。理想情况下,这也适用于具有运算符重载的用户定义类,但这是次要要求。

2 个答案:

答案 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/