gpt4 book ai didi

C#:找出代码中算术运算的结果类型(例如 int + double = double)

转载 作者:太空宇宙 更新时间:2023-11-03 22:55:42 24 4
gpt4 key购买 nike

我正在尝试想出一个函数来确定算术运算的结果类型,例如加法:

Type TypeOfAddition(Type leftType, Type rightType)
{
// ???
}

Type TypeOfMultiplication(Type leftType, Type rightType)
{
// ???
}

// ... same for subtraction and division

这些功能的预期结果可能很清楚;本质上,我的目标是(在运行时)执行与 Visual Studio 在执行算术运算时将类型推断为“var”类型变量时执行的相同操作。

例如,

public class MyClass
{
public static string operator +(MyClass left, double right)
{
// ...
}
}

TypeOfAddition(typeof(int), typeof(double)); // Should return typeof(double)
TypeOfAddition(typeof(string), typeof(int)); // Should return typeof(string)
TypeOfAddition(typeof(MyClass), typeof(double)); // Should return typeof(string)

我的基本想法是概念上的实现

Type TypeOfAddition(Type leftType, Type rightType)
{
return leftType.GetMethods().Single(x =>
x.Name == "op_Addition" &&
x.GetParamters().Count == 2 &&
x.GetParameters().Last().ParameterType == rightType);
}

但是

A) 这不适用于基本类型,如 int、double 等,它们似乎没有明确定义运算符重载,并且

B) 上面的 linq 子句还不能捕获所有情况(例如继承)

我可以对基本类型进行硬编码,并尝试为 B) 提出一个聪明的解决方案,但这似乎相对..不够优雅。

有没有更聪明/更容易/更好的解决方案来解决这个问题?请注意,我只想获得此类运算结果的理论类型,而不是实际显式执行算术运算。

谢谢!

最佳答案

它当然不漂亮,也肯定不快,但它似乎适用于我对其进行的基本测试。

请注意,您需要引用 Microsoft.CSharp.dll

Type TypeOfAddition<TLeft, TRight>()
{
object GetDefault<T>()
{
if (typeof(T).IsValueType)
{
return default(T);
}

if (typeof(T) == typeof(string))
{
return string.Empty;
}

return (T)FormatterServices.GetUninitializedObject(typeof(T));
}

var binder = Microsoft.CSharp.RuntimeBinder.Binder.BinaryOperation(
CSharpBinderFlags.None,
ExpressionType.Add,
null,
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}
);

var left = Expression.Parameter(typeof(TLeft));
var right = Expression.Parameter(typeof(TRight));

var func = Expression.Lambda(
Expression.Dynamic(binder, typeof(object), left, right),
new[] { left, right }
).Compile();

return func
.DynamicInvoke(GetDefault<TLeft>(), GetDefault<TRight>())
?.GetType() ?? typeof(object);
}

示例输出:

public class MyClass
{
public static string operator +(MyClass left, double right)
{
return "";
}
}

TypeOfAddition<string, int>().Dump(); // System.String
TypeOfAddition<int, double>().Dump(); // System.Double
TypeOfAddition<float, double>().Dump(); // System.Double
TypeOfAddition<MyClass, double>().Dump(); // System.String

这使用 Jeroen 在评论中提到的 (RuntimeBinder) 来创建附加 Binder 。然后构建动态表达式树以添加 TLeftTRight 的默认值。我必须添加一个名为 GetDefault 的小函数来将 string 解析为空字符串,因为我假设您在尝试时想看到 string添加 ""+ 0 而不是 null。如果您确实想看到空值,只需将 GetDefault 调用替换为 default(TLeft)default(TRight).

它不调用构造函数(由于使用 GetUninitializedObject )包含字符串的特殊情况。

可能有很多可能的改进,我洗耳恭听。

关于C#:找出代码中算术运算的结果类型(例如 int + double = double),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45486364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com