C# 指定派生类中的字段类型
出于向后兼容性的原因,我有一个矩形2D和一个矩形3D。在此过程中,类别“transform”字段的类型应从Transform2d更改为Transform3d,这是Transform2d的衍生版本。 下面是一个简化的示例:C# 指定派生类中的字段类型,c#,field,derived-class,C#,Field,Derived Class,出于向后兼容性的原因,我有一个矩形2D和一个矩形3D。在此过程中,类别“transform”字段的类型应从Transform2d更改为Transform3d,这是Transform2d的衍生版本。 下面是一个简化的示例: class Transform2 { protected float positionX; protected float positionY; } class Transform3 : Transform2 { protected float pos
class Transform2
{
protected float positionX;
protected float positionY;
}
class Transform3 : Transform2
{
protected float positionZ;
}
class Rectangle2d
{
protected Transform2 transform;
}
class Rectangle3d : Rectangle2d
{
// Does not work: Just hides Rectangle2d.transform
protected new Transform3 transform;
}
我不喜欢的一种解决方案是不使用转换类和直接字段:
class Rectangle2d
{
protected float positionX;
protected float positionY;
}
class Rectangle3d : Rectangle2d
{
protected float positionZ;
}
在我看来,当第二种方法起作用时,第一种方法只是第二种方法,有一些聚束,应该有一个干净的解决方案。至少它希望如此
版本:.NET Framework 4.6.1继承意味着一种
is-a
关系Rectangle3d
不是2d,因此它可能不应该继承自Rectangle2d
也就是说,如果你必须这样做,我建议你使用泛型
public abstract class Transform<T>
{
protected T transform;
}
public class Rectangle2d : Transform<Transform2> {}
public class Rectangle3d : Transform<Transform3> {}
公共抽象类转换
{
保护T变换;
}
公共类Rectangle2d:变换{}
公共类Rectangle3d:Transform{}
在这个模型中,2d和3d都有一个强类型的属性
transform
。继承意味着一种is-a
关系Rectangle3d
不是2d,因此它可能不应该继承自Rectangle2d
也就是说,如果你必须这样做,我建议你使用泛型
public abstract class Transform<T>
{
protected T transform;
}
public class Rectangle2d : Transform<Transform2> {}
public class Rectangle3d : Transform<Transform3> {}
公共抽象类转换
{
保护T变换;
}
公共类Rectangle2d:变换{}
公共类Rectangle3d:Transform{}
在这个模型中,2d和3d都有一个强类型的属性
transform
。您所要求的是不可能的,字段不能被覆盖。这就是为什么公共可见(以及受保护的
是公共可见的)字段会被设计指南引用的部分原因。但是,您可以将其抽象为属性:
class Rectangle2d
{
private Transform2d transform;
protected virtual Transform2d Transform => transform;
}
class Rectangle3d
{
private Transform3d transform;
protected override Transform2d Transform => transform;
}
理想情况下,基类应该尽可能少地依赖于具体的
transform
字段,而是使用transform
属性。但是,作为一个设计建议,考虑将常见行为抽象为<代码>抽象<代码>代码>矩形基> /COD>并使2D和3D变体从它继承而不是彼此继承。您现在正在使用Rectangle2d
创建一个相当脆弱的基类。您所要求的是不可能的,字段无法重写。这就是为什么公共可见(以及受保护的
是公共可见的)字段会被设计指南引用的部分原因。但是,您可以将其抽象为属性:
class Rectangle2d
{
private Transform2d transform;
protected virtual Transform2d Transform => transform;
}
class Rectangle3d
{
private Transform3d transform;
protected override Transform2d Transform => transform;
}
理想情况下,基类应该尽可能少地依赖于具体的
transform
字段,而是使用transform
属性。但是,作为一个设计建议,考虑将常见行为抽象为<代码>抽象<代码>代码>矩形基> /COD>并使2D和3D变体从它继承而不是彼此继承。您现在正在使用Rectangle2d
创建一个相当脆弱的基类。您的继承在我看来没有多大意义。3D变换/对象比2D更通用。。。如果以另一种方式执行,则问题会更少(例如,transform 2d实际上是一个变换3d,其中z固定为零等),使矩形3d
从2d副本继承是没有意义的-这就是您的问题!继承关系在这里没有意义,2D形状不是3D形状,3D形状也不是3D形状。@HimBromBeere 2D形状是3D形状,深度为0感谢您的回答。仅供理解:在我的应用程序中,我主要使用2d对象。3d对象很少见,但它们确实存在。当我从3d对象导出2d时,这更有意义,但我也会得到我想要避免的巨大开销。在我看来,你的继承没有多大意义。3d变换/对象比2d更一般。。。如果以另一种方式执行,则问题会更少(例如,transform 2d实际上是一个变换3d,其中z固定为零等),使矩形3d
从2d副本继承是没有意义的-这就是您的问题!继承关系在这里没有意义,2D形状不是3D形状,3D形状也不是3D形状。@HimBromBeere 2D形状是3D形状,深度为0感谢您的回答。仅供理解:在我的应用程序中,我主要使用2d对象。3d对象很少见,但它们确实存在。当我从3d对象导出2d时,这更有意义,但我也会得到我想要避免的巨大开销。