给定此类具有隐式强制转换运算符:
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;
}
我现在可以执行以下操作:
long a = 5;
MyDateTime b = a;
但不是以下内容:
long f = 5;
object g = f;
MyDateTime h = g;
这给出了编译时间:
无法将类型'object'隐式转换为'MyDateTime'。
对我有意义。
现在我修改上一个例子如下:
long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
编译好。现在我得到一个运行时InvalidCastException
:
无法将“System.Int64”类型的对象强制转换为MyDateTime'。
这告诉我C#隐式转换运算符仅在编译时应用,并且在.NET运行时试图动态地将对象转换为另一种类型时不应用。
我的问题:
顺便说一句,完整的应用程序是我使用Delegate.DynamicInvoke()
来调用一个带有MyDateTime
参数的函数,以及我传递给DynamicInvoke
的参数的类型很长。
答案 0 :(得分:14)
我说错了吗?
是的,是的,你是。为了挑剔,你应该说“用户定义的隐式转换”而不是“隐式转换” - 转换(几乎)总是显式的。但是你的推论是,重载决策选择哪个用户定义的转换在编译时调用 而不是在运行时是正确的。
还有其他方法吗?
是。在C#4中,如果您将“对象”键入为“动态”,那么我们在运行时再次启动编译器并重新执行操作数上的所有分析,就像它们的编译时类型一样是当前的运行时类型。正如您可能想象的那样,这并不便宜,但是如果您在紧密循环中执行此操作,我们对缓存非常聪明并重新使用结果。
答案 1 :(得分:-3)
我知道这是一个较旧的问题,但万一其他人偶然遇到同样的问题,这将编译并运行良好:
long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;
答案 2 :(得分:-4)