如果我有一个表达式Expression.Constant(3)和Expression.Constant(3d),它会将int转换为double,我该如何对它进行排序--“向上转换”呢?
我知道我可以使用Expression.Convert()进行转换,但是确定哪种类型可以隐式向上转换的最佳方法是什么呢?
我正在编写一个简单的方程式计算器,所以唯一期望的输入类型是值类型
发布于 2014-10-08 15:38:02
这里需要考虑的关键是,LINQ和都使用的language-agnostic代码模型被设计为System.Linq.Expressions。这样做的目的是为了创建一个“编译器”,它可以将任意语言的表达式转换为LINQ/DLR树。不同的语言都有自己的规则来规范哪些类型的转换是隐式的或显式的,所以表达式树API和编译器往往非常严格地要求类型完全匹配。“编译器编写器”(或生成这些表达式树的任何代码)的工作是显式地注入与源语言语义匹配所需的转换。
定制表达式语言的语义取决于您自己;您可以选择将它们建立在现有语言(如C# )的基础上,但在LINQ/DLR框架中找不到许多工具来告诉您“应该”隐式地进行哪种转换,因为没有标准的规则集;这些规则依赖于语言。无论您决定什么规则,最终都要由您将必要的转换注入到表达式树中。这是一个非平凡的任务,没有“一刀切”的解决方案可以简单地发布到StackOverflow。
好的方面是,在树中拥有“不必要的”Convert表达式成本很小;如果字节码级别从一种类型转换到另一种类型实际上是不操作,那么在编译表达式时不会发出额外的字节码。
发布于 2014-09-30 16:00:14
在浏览Reflector中的System.Linq.Expressions命名空间时,我发现了下面的方法,而不是动态方法。
public static bool IsImplicitNumericConversion(Type source, Type destination)
{
TypeCode typeCode = Type.GetTypeCode(source);
TypeCode code2 = Type.GetTypeCode(destination);
switch (typeCode)
{
case TypeCode.Char:
switch (code2)
{
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.SByte:
switch (code2)
{
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Byte:
switch (code2)
{
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.Int16:
switch (code2)
{
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.UInt16:
switch (code2)
{
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.Int32:
switch (code2)
{
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.UInt32:
switch (code2)
{
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.Int64:
case TypeCode.UInt64:
switch (code2)
{
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
return false;
case TypeCode.Single:
return (code2 == TypeCode.Double);
default:
return false;
}
return false;
}https://stackoverflow.com/questions/26123381
复制相似问题