有没有办法在C#中进行动态隐式类型转换?

时间:2010-01-18 23:59:23

标签: c# type-conversion dynamic-cast implicit-cast dynamic-invoke

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

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. 还有其他方法吗?
  3. 顺便说一句,完整的应用程序是我使用Delegate.DynamicInvoke()来调用一个带有MyDateTime参数的函数,以及我传递给DynamicInvoke的参数的类型很长。

3 个答案:

答案 0 :(得分:14)

  

我说错了吗?

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

  

还有其他方法吗?

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

答案 1 :(得分:-3)

我知道这是一个较旧的问题,但万一其他人偶然遇到同样的问题,这将编译并运行良好:

long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;

答案 2 :(得分:-4)