介绍
我知道"不允许在基类之间进行用户定义的转换".作为对此规则的解释,MSDN给出了"您不需要此运算符".
我确实理解不需要用户定义到基类的转换,因为这显然是隐式完成的.但是,我确实需要从基类转换.
在我目前的设计中,非托管代码的包装器,我使用指针存储在Entity类中.所有使用指针的类都派生自该Entity类,例如Body类.
因此我有:
方法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);
}
}
Run Code Online (Sandbox Code Playgroud)
这个演员是非法的.(注意,我没有打扰写入访问器).没有它,编译器将允许我这样做:
方法B.
(Body)myEntity
...
Run Code Online (Sandbox Code Playgroud)
但是,在运行时,我会得到一个例外,说这个演员是不可能的.
结论
因此,我需要从基类进行用户定义的转换,而C#拒绝它给我.使用方法A,编译器会抱怨,但代码在运行时逻辑上可以工作.使用方法B,编译器不会抱怨,但代码在运行时显然会失败.
在这种情况下我觉得奇怪的是,MSDN告诉我我不需要这个运算符,并且编译器就像隐含的一样(方法B).我应该做些什么?
我知道我可以使用:
解决方案A.
class Body : Entity
{
Body(IntPtr pointer) : base(pointer) { }
static Body FromEntity(Entity e)
{
return new Body(e.Pointer);
} …Run Code Online (Sandbox Code Playgroud) 我们创建Id32并Id64构造了包装来自DB的整数和长值,因此可以通过Json转换器(使用专用的自定义转换器)将它们显式处理为ID.
问题是我们从一个Dictionary<string, object>实际上是类似DataRow对象读取这些数据,其中string部分是列的名称,object部分是值.
所以在我们使用此代码读取值之前:
int myVal = (int)row["COLUMN"]
Run Code Online (Sandbox Code Playgroud)
我们希望此代码在这些更改后也能继续工作.
但由于row["COLUMN"]是object(@ compile-time)隐式转换失败,即使它实际上是Id32(@运行时).
以下显然有效:
int myVal = (Id32)row["COLUMN"]
Run Code Online (Sandbox Code Playgroud)
但有没有办法解决这个问题而不修改读取值的代码?
这是结构代码:
public struct Id32
{
public readonly int Value;
public Id32(int id) { this.Value = id; }
public static implicit operator int(Id32 id) { return id.Value; }
public static implicit operator Id32(int id) { return new Id32(id); }
}
Run Code Online (Sandbox Code Playgroud)