从基类用户自定义转换操作符 [英] User-defined conversion operator from base class

查看:102
本文介绍了从基类用户自定义转换操作符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

据我所知,用户定义的转换或从基类不准。 MSDN提供,作为解释这一规则,你不需要这个操作。

I am aware that "user-defined conversions to or from a base class are not allowed". MSDN gives, as an explanation to this rule, "You do not need this operator."

我不明白,一个用户自定义转换的的不需要基类,因为这显然是隐式进行。不过,我需要从一个转换的 的基类。

I do understand that an user-defined conversion to a base class is not needed, as this obviously done implicitly. However, I do need a conversion from a base class.

在我目前的设计,非托管code的包装,我用一个指针,存储在一个实体类。
使用指针的所有类从实体类派生,例如身体类。

In my current design, a wrapper of unmanaged code, I use a pointer, stored in an Entity class. All the classes using a pointer derive from that Entity class, for example, a Body class.

因此​​,我有:

方法A

class Entity
{
    IntPtr Pointer;

    Entity(IntPtr pointer)
    {
        this.Pointer = pointer;
    }
}

class Body : Entity
{
    Body(IntPtr pointer) : base(pointer) { }

    explicit operator Body(Entity e)
    {
        return new Body(e.Pointer);
    }
}

这是铸非法的。 (请注意,我没有理会写访问)。
没有它,编译器的将会的允许我这样做:

This cast is the illegal one. (Note that I didn't bother writing the accessors). Without it, the compiler will allow me to do:

方法B

(Body)myEntity
...

然而,在运行时,我会得到一个异常说这个转换是不可能的。

However, at runtime, I will get an exception saying this cast is impossible.

结论

所以我在这里,需要从的基类的用户自定义转换的和C#它拒绝了我。使用方法A,编译器会抱怨,但code将在运行逻辑上工作。使用方法B,编译器不会抱怨,但code将在运行时明显失败。

Therefore here I am, needing an user-defined conversion from a base class, and C# refuses it to me. Using method A, the compiler will complain but the code would logically work at runtime. Using method B, the compiler will not complain but the code will obviously fail at runtime.

我发现了什么在这种情况下,奇怪的是,MSDN告诉我,我不需要这个操作符,而编译器行为的,如果的,有可能隐含(方法B)。那我该怎么办?

What I find strange in this situation is that MSDN tells me I do not need this operator, and the compiler acts as if it was possible implicitly (method B). What am I supposed to do?

我知道我可以使用:

解决方案A

class Body : Entity
{
    Body(IntPtr pointer) : base(pointer) { }

    static Body FromEntity(Entity e)
    {
        return new Body(e.Pointer);
    }
}

解决方案B

class Body : Entity
{
    Body(IntPtr pointer) : base(pointer) { }

    Body(Entity e) : base(e.Pointer) { }
}

C液

class Entity
{
    IntPtr Pointer;

    Entity(IntPtr pointer)
    {
        this.Pointer = pointer;
    }

    Body ToBody()
    {
        return new Body(this.Pointer);
    }
}

不过说实话,所有这些的语法是可怕的,实际上应该转换。
因此,任何方法,使铸件工作?它是一个C#设计缺陷还是我错过的可能性?这是因为如果C#不相信我足够使用他们的等级制度,以写我自己的基站对孩子的转换。

But honestly, all the syntaxes for these are horrible and should in fact be casts. So, any way to make the casts work? Is it a C# design flaw or did I miss a possibility? It's as if C# didn't trust me enough to write my own base-to-child conversion using their cast system.

推荐答案

这不是一个设计缺陷。这里的原因:

It's not a design flaw. Here's why:

Entity entity = new Body();
Body body = (Body) entity;

如果你被允许在这里写自己的用户定义的转换,会有的两个的有效转换:尝试只是做一个正常的投(这是一个引用转换,preserving标识)和用户定义的转换。

If you were allowed to write your own user-defined conversion here, there would be two valid conversions: an attempt to just do a normal cast (which is a reference conversion, preserving identity) and your user-defined conversion.

应该使用哪个?你的真正的希望是如此,这些国家将做不同的事?

Which should be used? Would you really want is so that these would do different things?

// Reference conversion: preserves identity
Object entity = new Body();
Body body = (Body) entity;

// User-defined conversion: creates new instance
Entity entity = new Body();
Body body = (Body) entity;

育!疯狂这样的谎言,海事组织。不要忘记,在编译这个决定的编译时间的,仅根据的编译时间的类型所涉及的前pressions的。

Yuk! That way madness lies, IMO. Don't forget that the compiler decides this at compile-time, based only on the compile-time types of the expressions involved.

个人而言,我会用溶液C去 - 甚至可能使它成为一个虚拟的方法。这样机身可能的覆盖它只是返回这个,如果你希望它是身份preserving的在可能的情况的目标是创造一个新的对象,其中必要的。

Personally I'd go with solution C - and possibly even make it a virtual method. That way Body could override it to just return this, if you want it to be identity preserving where possible but creating a new object where necessary.

这篇关于从基类用户自定义转换操作符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆