c# - El operador de conversión explícita falla con el error "no se hace referencia al ensamblaje"
casting explicit (1)
Este es un problema muy poco frecuente y definitivamente hay muchas soluciones, pero me gustaría entender qué está sucediendo realmente y por qué no está funcionando.
Entonces tengo 3 ensamblajes en una solución de prueba, el primer ensamblaje tiene el tipo ClassA:
public class ClassA
{
public string Name { get; set; }
}
El segundo conjunto hace referencia al primer conjunto y tiene ClassB:
public class ClassB
{
public string Name { get; set; }
public static explicit operator ClassA(ClassB objB)
{
return new ClassA
{
Name = objB.Name
};
}
}
que tiene un operador explícito para emitir al tipo ClassA. Digamos que no podemos usar la herencia por alguna razón y solo usar la conversión como una forma conveniente de transformar un tipo en otro.
Ahora, el último conjunto hace referencia al segundo conjunto (¡y no al primero!) Y tiene el tipo ClassC:
public class ClassC
{
public string Name { get; set; }
public static explicit operator ClassB(ClassC objC)
{
return new ClassB
{
Name = objC.Name
};
}
}
que utiliza el operador de conversión explícita por la misma razón que ClassB.
Ahora, la parte interesante: si trato de convertir de ClassC a ClassB en mi código, así:
ClassC objC = new ClassC();
ClassB objB = (ClassB)objC;
Obtuve el siguiente error:
Error 1 El tipo ''FirstAssembly.ClassA'' se define en un ensamblaje al que no se hace referencia. Debe agregar una referencia al ensamblado ''FirstAssembly, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null''.
Podría crear fácilmente una nueva instancia de ClassB y simplemente inicializarla con valores de la instancia de ClassC (como hago dentro de un operador de conversión explícito), y funcionaría bien. Entonces, ¿qué está mal aquí?
En la sección 6.4.5 conversiones explícitas definidas por el usuario de la especificación de lenguaje C # (versión 4.0), se lee:
Una conversión explícita definida por el usuario del tipo S al tipo T se procesa de la siguiente manera:
• Determinar los tipos S0 y T0. Si S o T son tipos anulables, S0 y T0 son sus tipos subyacentes, de lo contrario S0 y T0 son iguales a S y T respectivamente.
• Encuentre el conjunto de tipos, D, a partir de los cuales se considerarán los operadores de conversión definidos por el usuario. Este conjunto consta de S0 (si S0 es una clase o estructura), las clases base de S0 (si S0 es una clase), T0 (si T0 es una clase o estructura) y las clases base de T0 (si T0 es una clase).
No define cómo el compilador "Buscará el conjunto de tipos", pero creo que busca en todas las clases relevantes en busca de candidatos para el siguiente paso:
• Encuentre el conjunto de operadores de conversión levantados y definidos por el usuario aplicables, U. Este conjunto consiste en los operadores de conversión implícitos o explícitos definidos por el usuario y levantados declarados por las clases o estructuras en D que se convierten de un tipo que abarca o abarca por S a un tipo que abarca o que abarca T. Si U está vacía, la conversión no está definida y se produce un error en tiempo de compilación.
Esto hace que intente resolver la referencia a ClassA.