Gotcha de conversión de grupo de método implícito (Parte 2)

Simplificado deesta pregunt y eliminó el posible efecto de LinqPad (no ofensivo), una aplicación de consola simple como esta:

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

Los resultados "falsos" del operadorceq en CIL del código anterior (visite la pregunta original para más detalles). Entonces mis preguntas son:

(1) Por qué== se está traduciendo aceq en lugar decall Delegate Equals?

Aquí no me importa el (des) ajuste entre Delegado y Acción. Por último, al evaluara == b, a es de tipoAction mientras b es unaDelegate. De la especificación:

7.3.4 Resolución de sobrecarga del operador binario

Una operación de la forma x op y, donde op es un operador binario sobrecargable, x es una expresión de tipo X e y es una expresión de tipo Y, se procesa de la siguiente manera:

• Se determina el conjunto de operadores candidatos definidos por el usuario proporcionados por X e Y para el operador de operación op (x, y). El conjunto consiste en la unión de los operadores candidatos proporcionados por X y los operadores candidatos proporcionados por Y, cada uno determinado utilizando las reglas del §7.3.5. Si X e Y son del mismo tipo, o si X e Y se derivan de un tipo base común, los operadores candidatos compartidos solo ocurren en el conjunto combinado una vez.

• Si el conjunto de operadores candidatos definidos por el usuario no está vacío, se convierte en el conjunto de operadores candidatos para la operación. De lo contrario, las implementaciones de operadores binarios predefinidos, incluidas sus formas elevadas, se convierten en el conjunto de operadores candidatos para la operación. Las implementaciones predefinidas de un operador dado se especifican en la descripción del operador (§7.8 a §7.12).

• Las reglas de resolución de sobrecarga de §7.5.3 se aplican al conjunto de operadores candidatos para seleccionar el mejor operador con respecto a la lista de argumentos (x, y), y este operador se convierte en el resultado del proceso de resolución de sobrecarga. Si la resolución de sobrecarga no puede seleccionar un solo mejor operador, se produce un error de tiempo de enlace.

7.3.5 Operadores candidatos definidos por el usuario

Dado un tipo T y un operador de operación op (A), donde op es un operador sobrecargable y A es una lista de argumentos, el conjunto de operadores candidatos definidos por el usuario proporcionados por T para el operador op (A) se determina de la siguiente manera:

• Determine el tipo T0. Si T es un tipo anulable, T0 es su tipo subyacente; de lo contrario, T0 es igual a T.

• Para todas las declaraciones de operaciones de operador en T0 y todas las formas levantadas de dichos operadores, si al menos un operador es aplicable (§7.5.3.1) con respecto a la lista de argumentos A, entonces el conjunto de operadores candidatos consta de todos los operadores aplicables en T0.

• De lo contrario, si T0 es un objeto, el conjunto de operadores candidatos está vacío.

• De lo contrario, el conjunto de operadores candidatos proporcionados por T0 es el conjunto de operadores candidatos proporcionados por la clase base directa de T0, o la clase base efectiva de T0 si T0 es un parámetro de tipo.

De la especificación, ayb tienen una misma clase baseDelegate, obviamente la regla del operador== definido enDelegate debe aplicarse aquí (el operador == invoca Delegate.Equals esencialmente). Pero ahora parece que la lista de candidatos de operadores definidos por el usuario está vacía y por finObject == Está aplicado

(2) ¿Debería (el código FCL obedecer la especificación del lenguaje C #)? Si no, mi primera pregunta no tiene sentido porque algo está especialmente tratado. Y luego podemos responder a todas estas preguntas usando "oh, es un tratamiento especial en FCL, pueden hacer algo que nosotros no podemos. La especificación es para programadores externos, no seas tonto".

Respuestas a la pregunta(8)

Su respuesta a la pregunta