我可以使用显式运算符来创建派生类吗?

发布于 2024-10-16 14:01:09 字数 512 浏览 6 评论 0原文

class Base
{
}

class Derived1 : Base
{
}

class Derived2 : Base
{
    public static explicit operator Derived1(Derived2 d2)
    {
        return new Derived1();
    }
}

class Test
{
    static void Main()
    {
        Base bd2 = new Derived2();

        Derived1 d2ConvertedD1 = (Derived1)bd2; //throws InvalidCastException

    }
}

无法将“ConsoleApplication1.Derived2”类型的对象转换为“ConsoleApplication1.Derived1”类型。

为什么?我的运算符转换出了什么问题?

class Base
{
}

class Derived1 : Base
{
}

class Derived2 : Base
{
    public static explicit operator Derived1(Derived2 d2)
    {
        return new Derived1();
    }
}

class Test
{
    static void Main()
    {
        Base bd2 = new Derived2();

        Derived1 d2ConvertedD1 = (Derived1)bd2; //throws InvalidCastException

    }
}

Unable to cast object of type 'ConsoleApplication1.Derived2' to type 'ConsoleApplication1.Derived1'.

Why? What is wrong with my operator conversion?

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

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

发布评论

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

评论(5

不必在意 2024-10-23 14:01:09

问题是您的自定义转换没有被使用,因为 bd2 的编译时类型是 Base,而不是 Derived2。编译器甚至没有考虑您的自定义转换,因此它只是包含正常的转换 - 由于显而易见的原因而失败。 (我假设您了解这种失败,否则您不会首先创建自定义转换。)

编译器根据操作数的编译时类型选择运算符和转换。

虽然您可以首先转换为Derived2或更改bd2的声明,但我个人会完全改变策略,并再次查看更大的图景。你想做什么,为什么?例如,Base 中的虚拟方法是否更有意义?

The trouble is that your custom conversion isn't being used, because the compile-time type of bd2 is Base, not Derived2. The compiler isn't even considering your custom conversion, so it's just including a normal cast - which is failing for the obvious reason. (I assume you understand that failure, otherwise you wouldn't have created the custom conversion to start with.)

Operators and conversions are chosen by the compiler based on the compile-time types of the operands.

While you could cast to Derived2 first or change the declaration of bd2, I would personally change tack completely, and look at the bigger picture again. What are you trying to do, and why? Would a virtual method in Base make more sense, for example?

溺渁∝ 2024-10-23 14:01:09

您只能在层次结构中上下转换类,而不能跨层次转换。

You can only cast classes up and down the hierarchy, not across.

成熟的代价 2024-10-23 14:01:09

查看操作员的签名:

public static explicit operator Derived1(Derived2 d2);

注意它是静态。您所看到的与方法重载解析的限制类似。

这本质上与下面输出“Object”而不是“String”的原因相同:

static void WriteObject(object obj) { Console.WriteLine("Object"); }
static void WriteObject(string str) { Console.WriteLine("String"); }

object obj = "I am a string.";
WriteObject(obj);

也就是说,编译器需要在编译时选择重载。在从 Base 转换为 Derived1 的情况下,正确的签名不会发生重载,因此它会尝试实际的向下转换。正如其他人提到的,将 bd2 声明为 Derived2 可以通过允许编译器选择自定义转换来“修复”此问题。

Look at the signature of your operator:

public static explicit operator Derived1(Derived2 d2);

Notice it's static. What you're seeing is similar to the limitation of method overload resolution.

It's essentially the same reason the below outputs "Object" instead of "String":

static void WriteObject(object obj) { Console.WriteLine("Object"); }
static void WriteObject(string str) { Console.WriteLine("String"); }

object obj = "I am a string.";
WriteObject(obj);

That is, the compiler needs to pick an overload at compile-time. In the case of casting from a Base to a Derived1, there is no overload with the proper signature, so it attempts an actual downcast. Declaring bd2 as Derived2, as others have mentioned, would "fix" this by enabling the compiler to select your custom conversion.

南…巷孤猫 2024-10-23 14:01:09

类 Derived2 不继承自类 Derived1,这就是失败的原因。

以下内容是有效的:

基础 d2ConvertedBase = (基础) bd2;

如果 Derived2 继承自 Derived1,则您的尝试将是有效的。

The class Derived2 does not inherit from the class Derived1, that is why this fails.

The following would be valid:

Base d2ConvertedBase = (Base) bd2;

If Derived2 was to inherit from Derived1, what you tried would be valid.

独守阴晴ぅ圆缺 2024-10-23 14:01:09

投射到基类。如果您要创建复杂的类层次结构,请考虑实现接口并进行基于接口的编程。

Cast to the base class. If you're creating a complex class heirarchy, consider implementing interfaces and doing interface based programming.

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