dado esta clase con un operador de conversión implícita:¿Hay alguna forma de hacer fundición de tipo implícita dinámica en C#?
public class MyDateTime
{
public static implicit operator MyDateTime(System.Int64 encoded)
{
return new MyDateTime(encoded);
}
public MyDateTime(System.Int64 encoded)
{
_encoded = encoded;
}
System.Int64 _encoded;
}
ahora puedo hacer lo siguiente:
long a = 5;
MyDateTime b = a;
pero no el siguiente:
long f = 5;
object g = f;
MyDateTime h = g;
Esto da un tiempo de compilación:
No se puede convertir implícitamente el tipo 'objeto' a 'MiTiempoTiempo'.
Tiene sentido para mí.
Ahora modifique el ejemplo anterior de la siguiente manera:
long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
Este compila bien. Ahora obtengo un tiempo de ejecución InvalidCastException
:
No se puede convertir el objeto del tipo 'System.Int64' para escribir MyDateTime '.
Esto me dice que los operadores de colada implícita C# se aplican solo en tiempo de compilación, y no se aplican cuando el tiempo de ejecución de .NET está intentando lanzar dinámicamente un objeto a otro tipo.
Mis preguntas:
- Estoy en lo correcto?
- ¿Hay alguna otra forma de hacerlo?
Por cierto, la aplicación completa es que estoy usando Delegate.DynamicInvoke()
llamar a una función que toma un parámetro MyDateTime
, y el tipo de argumento que estoy pasando a DynamicInvoke
es mucho.
Solo por curiosidad, ¿cuáles son las razones por las que los operadores no se comportan más como métodos en tiempo de ejecución? Dada tu respuesta, se siente como si fueran meros azúcares sintácticos y no mucho más. En mi opinión, haría C * aún más poderoso si este tipo de operadores se promocionan como miembros de primera clase de cualquier tipo (lo que significa que se convierten en parte de todas las otras bondades orientadas a objetos como herencia, anulación e interconexión). ¿Aprovechar estos en tiempo de ejecución de forma predeterminada implica cambios importantes en el diseño y la implementación del lenguaje? – MarioDS
@MDeSchaepmeester: Tiene razón en que hay un poco de desconexión aquí. Compare el diseño de int a decimal, por ejemplo. Puede decir 'Func add = decimal.Add;' pero no hay forma de hacer lo mismo para int; tienes que decir 'Func add = (x, y) => x + y'. Hubiera sido agradable, creo, si todos los tipos incorporados se hubieran diseñado como Decimal, y luego el tiempo de ejecución o el compilador podrían elegir reducirlos a operaciones más fundamentales por motivos de rendimiento. Pero este tipo de consistencia realmente se sigue de una mentalidad "funcional". –
@MDeSchaepmeester: sospecho que los diseñadores originales del tiempo de ejecución simplemente no estaban pensando en ese tipo de abstracción funcional unificadora al diseñar el sistema de tipos y las operaciones en tipos incorporados. Y, por supuesto, también es extraño que el decimal tenga un operador + y un método Add. ¡Y ni siquiera me pidas que inicie la docena de formas para representar la operación de igualdad! Es un poco un desastre realmente. La próxima vez que diseñe un marco desde cero, consiga esto pronto. –