簡體   English   中英

Linq和Equality Operator:類型'System.Int32'的表達式不能用於'System.Object'類型的參數

[英]Linq and the Equality Operator: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object'

我正在嘗試覆蓋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轉換為Object的任何想法,但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有什么問題? 重新刪除int vs null ,嘗試int?

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

您應該查看本文以檢查可以為空的類型。

http://msdn.microsoft.com/en-us/library/ms366789.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM