gpt4 book ai didi

c# - Linq 和相等运算符 : Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object'

转载 作者:可可西里 更新时间:2023-11-01 09:09:42 24 4
gpt4 key购买 nike

我试图重写 C# 中的相等 (==) 运算符来处理任何类型与自定义类型的比较(自定义类型实际上是 null 周围的包装器/框)。

所以我有这个:

internal sealed class Nothing
{
public override bool Equals(object obj)
{
if (obj == null || obj is Nothing)
return true;
else
return false;
}

public static bool operator ==(object x, Nothing y)
{
if ((x == null || x is Nothing) && (y == null || y is Nothing))
return true;
return false;
}
...
}

现在如果我像这样打电话:

Nothing n = new Nothing();
bool equal = (10 == n);

它工作得很好。但是,如果我尝试通过 Linq 表达式树做同样的事情:

exp = Expression.Equal(
Expression.Constant(10),
Expression.Constant(new Nothing(), typeof(Nothing))
);

它抛出异常:

System.ArgumentException : Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean op_Equality(System.Object, PARTSFinder.Rules.Runtime.RulesNothing)'
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodInfo method, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.ValidateCallArgs(Expression instance, MethodInfo method, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments)
at System.Linq.Expressions.ExpressionCompiler.GenerateBinaryMethod(ILGenerator gen, BinaryExpression b, StackType ask)

关于为什么基本系统可以将 Int32 转换为对象,但 Linq 不能,或者我如何解决这个问题,有什么想法吗?

这整件事都被盯上了,因为 Linq 一开始也无法将 Int32 与 Object 进行比较:

exp = Expression.Equal(
Expression.Constant(10),
Expression.Constant(null)
);

抛出一个异常,说明“System.Int32”和“System.Object”没有比较运算符。


快速跟进:

以下操作没有问题:

exp = Expression.Equal(
Expression.Constant(10, typeof(object)),
Expression.Constant(new Nothing(), typeof(Nothing))
);

exp = Expression.Equal(
Expression.Constant(10, typeof(object)),
Expression.Constant(null)
);

所以专门将所有内容都转换为对象。那么 Linq 只是不在内部处理继承吗?太烦人了...


跟进#2:

我也试过使用自定义比较方法:

exp = Expression.Equal(
Expression.Constant(10),
Expression.Constant(null),
false,
this.GetType().GetMethod("ValueEquals", BindingFlags.Public | BindingFlags.Static)
);

public static bool ValueEquals(object x, object y)
{
if (x == null && y == null)
return true;
if (x.GetType() != y.GetType())
return false;
return x == y;
}

这也抛出一个异常:

System.InvalidOperationException : The operands for operator 'Equal' do not match the parameters of method 'ValueEquals'.
at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)

但是再次将所有内容直接转换为对象:

exp = Expression.Equal(
Expression.Constant(10, typeof(object)),
Expression.Constant(null, typeof(object)),
false,
this.GetType().GetMethod("ValueEquals", BindingFlags.Public | BindingFlags.Static)
);

所以我想我有我的解决方法……将所有内容都转换为对象并使用自定义比较方法。我仍然很惊讶 Linq 不会像普通 C# 那样自动进行转换。

最佳答案

null 有什么问题?关于缺少的 intnull,请尝试 int?:

exp = Expression.Equal(
Expression.Constant(10, typeof(int?)),
Expression.Constant(null, typeof(int?))
);

关于c# - Linq 和相等运算符 : Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/840150/

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