12

给定带有隐式强制转换运算符的此类:

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 运行时尝试将对象动态转换为另一种类型时应用。

我的问题:

  1. 我对么?
  2. 还有其他方法可以做到这一点吗?

顺便说一句,完整的应用程序是我Delegate.DynamicInvoke()用来调用一个带MyDateTime参数的函数,而我传递给的参数的类型DynamicInvoke是 long。

4

3 回答 3

14

我对么?

是的,是的,你是。为了挑剔,您应该说“用户定义的隐式转换”而不是“隐式转换”——转换(几乎)总是显式的。但是您推断重载解析选择在编译时而不是在运行时调用哪个用户定义的转换是正确的。

还有其他方法可以做到这一点吗?

是的。在 C# 4 中,如果您将“对象”键入为“动态”,那么我们会在运行时再次启动编译器并对操作数重新执行所有分析,就好像它们的编译时类型是当前运行时类型一样。正如您可能想象的那样,这并不便宜,尽管如果您在一个紧密的循环中执行此操作,我们在缓存和重用结果方面非常聪明。

于 2010-01-19T00:27:35.757 回答
-3

我知道这是一个较老的问题,但如果其他人偶然发现同样的问题,这将编译并运行良好:

long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;
于 2013-01-30T08:03:15.903 回答
-4

添加显式运算符应该可以工作:http: //msdn.microsoft.com/en-us/library/85w54y0a (VS.80).aspx

于 2010-01-19T00:03:17.063 回答