Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 指定派生类中的字段类型_C#_Field_Derived Class - Fatal编程技术网

C# 指定派生类中的字段类型

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

出于向后兼容性的原因,我有一个矩形2D和一个矩形3D。在此过程中,类别“transform”字段的类型应从Transform2d更改为Transform3d,这是Transform2d的衍生版本。 下面是一个简化的示例:

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时,这更有意义,但我也会得到我想要避免的巨大开销。