Gotcha de conversão de grupo de método implícito (parte 2)

Simplificado deessa questã e se livrou do possível efeito do LinqPad (sem ofensas), um aplicativo simples de console como este:

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();
    }        
}

Os resultados "falsos" do operadorceq no CIL do código acima (visite a pergunta original para obter detalhes). Então, minhas perguntas são:

(1) Por que== está traduzindo paraceq ao invés decall Delegate Equals?

Aqui não me importo com a (des) quebra entre Delegado e Ação. Por fim, ao avaliara == b, a é do tipoAction enquanto b é aDelegate. Das especificações:

.3.4 Resolução de sobrecarga do operador binário

Uma operação do formato x op y, em que op é um operador binário sobrecarregável, x é uma expressão do tipo X e y é uma expressão do tipo Y, é processada da seguinte forma:

• O conjunto de operadores candidatos definidos pelo usuário fornecidos por X e Y para o operador de operação op (x, y) é determinado. O conjunto consiste na união dos operadores candidatos fornecidos por X e dos operadores candidatos fornecidos por Y, cada um determinado de acordo com as regras do §7.3.5. Se X e Y forem do mesmo tipo, ou se X e Y forem derivados de um tipo de base comum, os operadores candidatos compartilhados ocorrerão apenas no conjunto combinado uma ve

• Se o conjunto de operadores candidatos definidos pelo usuário não estiver vazio, ele se tornará o conjunto de operadores candidatos à operação. Caso contrário, as implementações de operadores binários op predefinidas, incluindo suas formas levantadas, tornam-se o conjunto de operadores candidatos à operação. As implementações predefinidas de um determinado operador são especificadas na descrição do operador (§7.8 a §7.12

• As regras de resolução de sobrecarga de §7.5.3 são aplicadas ao conjunto de operadores candidatos para selecionar o melhor operador com relação à lista de argumentos (x, y), e esse operador se torna o resultado do processo de resolução de sobrecarga. Se a resolução de sobrecarga falhar na seleção de um único melhor operador, ocorrerá um erro no tempo de ligaçã

.3.5 Operadores definidos pelo usuário candidatos

Dado um tipo T e um operador de operação op (A), em que op é um operador sobrecarregável e A é uma lista de argumentos, o conjunto de operadores definidos pelo usuário candidatos fornecidos por T para o operador op (A) é determinado da seguinte forma:

• Determine o tipo T0. Se T é um tipo anulável, T0 é seu tipo subjacente, caso contrário, T0 é igual a T.

• Para todas as declarações de operação em T0 e todas as formas levantadas de tais operadores, se pelo menos um operador for aplicável (§7.5.3.1) com relação à lista de argumentos A, o conjunto de operadores candidatos consistirá em todos os operadores aplicáveis em T0.

• Caso contrário, se T0 for um objeto, o conjunto de operadores candidatos estará vazi

• Caso contrário, o conjunto de operadores candidatos fornecido por T0 é o conjunto de operadores candidatos fornecidos pela classe base direta de T0 ou pela classe base efetiva de T0 se T0 for um parâmetro de tipo.

Para as especificações, aeb têm a mesma classe baseDelegate, obviamente a regra do operador== definido emDelegate deve ser aplicado aqui (o operador == invoca Delegate.Equals essencialmente). Mas agora parece que a lista de candidatos de operadores definidos pelo usuário está vazia e, finalmente,Object == é aplicado

(2) O código FCL deve obedecer às especificações da linguagem C #? Se não, minha primeira pergunta não tem sentido, porque algo é especialmente tratado. E então podemos responder a todas essas perguntas usando "oh, é um tratamento especial no FCL, eles podem fazer algo que não podemos. A especificação é para programadores externos, não seja bobo".

questionAnswers(8)

yourAnswerToTheQuestion