隐式方法组转换的疑难杂症(第二部分) [英] Implicit method group conversion gotcha (Part 2)

查看:99
本文介绍了隐式方法组转换的疑难杂症(第二部分)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题并摆脱可能从LinqPad影响(不offsensive ),一个简单的控制台应用程序是这样的:

Simplified from this question and got rid of possible affect from LinqPad(no offsensive), a simple console application like this:

public class Program
{
    static void M() { }    
    static void Main(string[] args)
    {
        Action a = new Action(M);
        Delegate b = new Action(M);
        Console.WriteLine(a == b);      //got False here
        Console.Read();
    }        
}



从运营商的假的结果 CEQ 在上面的代码CIL(参观有关详细信息,原来的问题)。所以我的问题是:

The "false" results from the operator ceq in CIL of the code above(visit the original question for details). So my questions are:

(1)为什么 == 被翻译成 CEQ 而不是调用委托等于

(1) Why == is translating to ceq instead of call Delegate Equals?

在这里,我不关心(UN代表和行动之间)包装。在最后,当评估 A == b ,一个类型为动作,而b是代表。从规格:

Here I don't care about the (un)wrapping between Delegate and Action. At the very last, when evaluating a == b, a is of type Action while b is a Delegate. From the spec:

7.3.4二元运算符重载解析

7.3.4 Binary operator overload resolution

这是操作在x op y形式,其中op是可重载的二元运算,x是X类型的表达式:
和y是Y类型的表达式,按如下方式处理:

An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows:

•由X和Y为$提供b $ b中的运算operator op候选的用户定义运算符(X,Y)是确定的。该组包​​括用X提供的候选运营商和由Y提供候选
运营商的
结合的,每一个确定使用§7.3.5的规则。如果
X和Y是相同的类型,或者如果X和Y是从一个共同的
基型衍生,然后共享候选运营商仅发生在组合
设置一次。

• The set of candidate user-defined operators provided by X and Y for the operation operator op(x, y) is determined. The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of §7.3.5. If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once.

•如果候选的用户定义运算符是不是
空的,那么它就会成为
操作的候选操作符集。否则,预定义的二进制操作符op
实施方式中,包括它们的解除的形式,成为该操作的集合
候选运算。一个给定的操作者的预定义实现
在操作
(§7.8通过§7.12)的说明指定。

• If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Otherwise, the predefined binary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. The predefined implementations of a given operator are specified in the description of the operator (§7.8 through §7.12).

•的第7.5.3节中的重载决策规则是
应用于候选运算符集,以选择最佳运营商
相对于该参数列表(x,y)的,而这个操作符变为
重载决策过程的结果。如果重载
未能选出单个最佳运算符,则发生绑定时错误。

• The overload resolution rules of §7.5.3 are applied to the set of candidate operators to select the best operator with respect to the argument list (x, y), and this operator becomes the result of the overload resolution process. If overload resolution fails to select a single best operator, a binding-time error occurs.

7.3.5候选用户定义运算符

7.3.5 Candidate user-defined operators

给定一个T类型和运算operator op(A),其中op是可重载运算符,A是一个参数列表,由
提供的候选的用户定义运算

Given a type T and an operation operator op(A), where op is an overloadable operator and A is an argument list, the set of candidate user-defined operators provided by T for operator op(A) is determined as follows:

•确定类型
T0:T表示操作符op(A)确定如下。如果T是可空类型,T0是其基础类型,否则T0
等于T.

• Determine the type T0. If T is a nullable type, T0 is its underlying type, otherwise T0 is equal to T.

•对于T0和所有所有的操作op声明解除
形式,运营商,如果至少一个操作符适用
(§7.5.3.1)相对于参数列表A,然后设置
候选运算包括所有此类适用的运营商在T0。

• For all operator op declarations in T0 and all lifted forms of such operators, if at least one operator is applicable (§7.5.3.1) with respect to the argument list A, then the set of candidate operators consists of all such applicable operators in T0.

•否则,如果T0为对象,候选运算符集是空的。

• Otherwise, if T0 is object, the set of candidate operators is empty.

•否则,T0提供的候选运算符集是直接基类T0,还是
有效基类T0提供的候选运算符的设定
如果T0为类型参数。

• Otherwise, the set of candidate operators provided by T0 is the set of candidate operators provided by the direct base class of T0, or the effective base class of T0 if T0 is a type parameter.

从规范,A和b具有相同的基类代表,很明显运营商规则 == 代表定义应该应用在这里(运营商==调用Delegate.Equals本质上)。但现在它看起来像用户定义的运营商的候选名单是空的,最后对象== 被应用。

From the spec, a and b have a same base class Delegate, obviously the operator rule == defined in Delegate should be applied here(the operator == invokes Delegate.Equals essentially). But now it looks like the candidate list of user-defined operators is empty and at last Object == is applied.

(2)如果(确实)整箱代码服从C#语言规范?如果没有,我的第一个问题是没有意义的,因为事情是经过特殊处理的。然后我们就可以回答所有使用这些问题:哦,这是在FCL特殊处理,他们可以做一些我们做不到的。该规范是外界程序员,别傻了。

(2) Should(Does) the FCL code obey the C# language spec? If no, my first question is meaningless because something is specially treated. And then we can answer all of these questions using "oh, it's a special treatment in FCL, they can do something we can't. The spec is for outside programmers, don't be silly".

推荐答案

有两种类型的运算符:用户自定义的运营商和预定义运算符。 7.3.5节候选用户定义运算符并不适用于预定义的运营商。
例如,小数运营商看起来像用户定义的运营商在反编译器,但C#将它们视为预定义的运营商和应用数值提升他们(数值提升不适用于用户自定义操作员)。

There are two types of operators: user-defined operators and predefined operators. Section 7.3.5 "Candidate user-defined operators" does not apply to predefined operators. For example, the operators on decimal look like user-defined operators in a decompiler, but C# treats them as predefined operators and applies numeric promotion to them (numeric promotion is not applied to user-defined operators).

第7.10.8委托相等商定义 ==操作符(委托代表)预定义运算符,所以我认为所有有关用户定义的运营规则并不适用于该运营商(虽然这不是100%,在规范清楚在这种情况下, 。预定义的操作者不适用,只要用户自定义操作员)

Section 7.10.8 "Delegate equality operators" defines operator ==(Delegate, Delegate) as a predefined operator, so I'd think that all the rules about user-defined operators don't apply to this operator (although this isn't 100% clear in the spec as in this case, the predefined operator doesn't apply whenever the user-defined operator would).

Every delegate type implicitly provides the following predefined comparison operators: 
bool operator ==(System.Delegate x, System.Delegate y);
bool operator !=(System.Delegate x, System.Delegate y); 



System.Delegate 本身不被视为一个委托类型,因此对于重载决议的唯一候选人是 ==操作符(对象,对象)

But System.Delegate itself is not considered a delegate type, so the only candidate for overload resolution is operator ==(object, object).

这篇关于隐式方法组转换的疑难杂症(第二部分)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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