LINQ和平等运营商:防爆$ P $类型'System.Int32的“的pssion不能用于类型参数'System.Object的' [英] Linq and the Equality Operator: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object'

查看:355
本文介绍了LINQ和平等运营商:防爆$ P $类型'System.Int32的“的pssion不能用于类型参数'System.Object的'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图重写等式(==)运算符在C#中处理比较任何类型的自定义类型(自定义类型真的是围绕空包装/箱)。

I'm trying to override the equality (==) operator in C# to handle comparing any type to a custom type (the custom type is really a wrapper/box around 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;
	}
   ...
}

现在,如果我做出这样一个电话:

Now if I make a call like:

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

这工作完全正常。但是,如果我试图通过一个LINQ EX pression树做同样的事情:

It works perfectly fine. However, if I try to do this same thing through a Linq expression tree:

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

这引发异常:

It throws the exception:

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的不行,或者我如何才能解决这个问题的任何想法?

Any ideas on why the base system can convert Int32 to Object, but Linq can't, or how I can fix this?

这件事瞪大了眼睛,因为LINQ的也无法比较的Int32摆在首位,以对象:

This whole thing stared because Linq also can't compare Int32 to Object in the first place:

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

抛出一个异常,说明没有比较运营商System.Int32的和System.Object的。

Throws an exception stating that there is no comparison operator for "System.Int32" and "System.Object".


快速后续:

没有问题,下面做的工作:

The following do work without issue:

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的只是内部没有处理继承?那是pretty的讨厌...

So specifically casting everything to object. So does Linq just not handle inheritance internally? Thats pretty annoying...


跟帖#2:

我也尝试过使用一个自定义的比较方法:

I also tried using a custom comparison method:

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)

不过,再铸一切直接反对作品:

But again casting everything directly to object works:

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

所以我想我有我的解决办法......一切都投对象,并使用自定义的比较方法。我仍然惊讶的LINQ自动为普通的C#确实没有做转换。

So I guess I have my workaround... cast everything to object and use a custom comparison method. I'm still surprised Linq doesn't do the conversion automatically as normal C# does.

推荐答案

什么是错的空?再缺少 INT VS ,试试 INT ?:

What is wrong with null? Re the missing int vs null, try int?:

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

这篇关于LINQ和平等运营商:防爆$ P $类型'System.Int32的“的pssion不能用于类型参数'System.Object的'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆