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

发布于 2024-08-17 22:54:30 字数 1109 浏览 8 评论 0原文

给定这个类带有隐式转换运算符:

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 参数的函数,以及参数的类型 I' m 传递给DynamicInvoke 是一个长整型。

Given this class with an implicit cast operator:

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;
}

I can now do the following:

long a = 5;
MyDateTime b = a;

But NOT the following:

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

This gives a compile time:

Cannot implicitly convert type 'object' to 'MyDateTime'.

Makes sense to me.

Now I modify the previous example as follows:

long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;

This compiles fine. Now I get a runtime InvalidCastException:

Unable to cast object of type 'System.Int64' to type MyDateTime'.

This tells me that C# implicit cast operators are applied at compile time only, and are not applied when the .NET runtime is attempting to dynamically cast an object to another type.

My questions:

  1. Am I correct?
  2. Is there some other way to do this?

By the way, the full application is that I'm using Delegate.DynamicInvoke() to call a function that takes a MyDateTime parameter, and the type of the argument I'm passing to DynamicInvoke is a long.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

窗影残 2024-08-24 22:54:30

我说得对吗?

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

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

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

Am I correct?

Yes, yes you are. To be nit-picky, you should be saying "user-defined implicit conversion" rather than "implicit cast" -- a cast is (almost) always explicit. But your deduction that overload resolution chooses which user-defined conversion to call at compile time and not at run time is correct.

Is there some other way to do this?

Yes. In C# 4 if you type your "object" as "dynamic" then we start up the compiler again at runtime and re-perform all the analysis on the operands as though their compile-time types were the current run-time types. As you might imagine, this is not cheap, though we are very smart about caching and re-using the results should you do this in a tight loop.

终止放荡 2024-08-24 22:54:30

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

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

I know this is an older question but in case anyone else stumbles upon the same problem, this will compile and run fine:

long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文