C# 向下转换继承类中基类中声明的对象
我正在为API创建一个插件,但在继承方面有问题。有没有一种方法可以在继承自基类的类中“自动”向下转换在基类中声明的对象 我的班级结构如下:C# 向下转换继承类中基类中声明的对象,c#,inheritance,C#,Inheritance,我正在为API创建一个插件,但在继承方面有问题。有没有一种方法可以在继承自基类的类中“自动”向下转换在基类中声明的对象 我的班级结构如下: abstract class MyPart { public Part modelObject; ... } class MyPlate : MyPart { public ArraList points; // from API ... } class Floor : MyPlate { ... } Part是
abstract class MyPart
{
public Part modelObject;
...
}
class MyPlate : MyPart
{
public ArraList points; // from API
...
}
class Floor : MyPlate
{
...
}
Part
是一个API类,其类结构如下所示:
class Part
class Plate : Part
现在,在MyPlate
和Floor
类中的代码中,我需要使用Plate modelObject
来访问它的方法。目前,我通过向下转换modelObject
来实现这一点:
(modelObject as Plate).doSomething;
虽然我想让它更简单一些,但这种方法还是有效的。然而,主要的问题是,当我试图访问modelObject
的成员时,我无法将它们作为引用。例如,当我试图声明点时,它不引用模型对象。点
:
points = (modelObject as Plate).points;
points = null; // modelObject.points != null
有没有一种方法可以将变量声明为对modelObject
的引用,以便对其进行操作?当您将点设置为null
时,您将清空范围中名为“points”的引用,而不是实际的变量。如果您真的不想只做modelObject.points=null
(您通常只做),您希望通过ref操作它来实际访问它
看
也就是说,我不知道为什么要向下转换对象,因为我们看不到足够的信息来确定这一点。当您将点设置为null
时,您将清空范围中名为“points”的引用,而不是实际变量。如果您真的不想只做modelObject.points=null
(您通常只做),您希望通过ref操作它来实际访问它
看
也就是说,我不确定您为什么要向下投射这些对象,因为我们看不到足够的情况来确定这一点。您正在创建引用的副本<代码>点=(模型对象为图版)。点
So点
和(模型对象为图版)。点
指向相同的内存。当您将null
分配给点时,一个参考被清除。另一个仍然存在
如果您想要(模型对象为图版)。点代码>设置为空。只需使用:(modelObject作为模板)。points=null代码>
这与铸造没有任何关系。您正在创建参考文件的副本<代码>点=(模型对象为图版)。点
So点
和(模型对象为图版)。点
指向相同的内存。当您将null
分配给点时,一个参考被清除。另一个仍然存在
如果您想要(模型对象为图版)。点代码>设置为空。只需使用:(modelObject作为模板)。points=null代码>
这与铸造没有任何关系。这实际上是两个问题。关于为什么你的观点不会被删除的部分已经回答了。但为了完整起见,这里是总结:
删除引用
调用var points=(modelObject为图版).points
时,将引用复制到modelObject
的points
对象。使用points=null
只需删除(null)对modelObject
的点的引用,但modelObject
仍保留对点的引用
要删除modelObject
对点的引用,请调用(modelObject为图版)。points=null
子类中的向下投射
但是对于您的主要问题,如何自动向下转换子类中的对象。有两种方法可以实现这一点。方法隐藏和泛型:
方法隐藏
Meth隐藏基类的方法或其他成员,并为名称提供新的含义。这样,就可以给子类成员另一个含义和另一个返回类型。要实现这一点,您应该将modelObject封装在属性中。您的代码如下所示:
abstract class MyPart
{
private Part modelObject;
public Part ModelObject
{
get { return modelObject; }
set { modelObject = value; }
}
...
}
class MyPlate : MyPart
{
public new Plate ModelObject
{
get { return base.ModelObject as Plate; }
set { base.ModelObject = value; }
public ArraList points; // from API
...
}
class Floor : MyPlate
{
...
}
注意,在子类中使用base.ModelObject
。这使您仍然可以访问基类ModelObject,尽管您给ModelObject赋予了新的含义。除了方法重写之外,您保留基类成员,并且只提供具有相同名称的另一个含义
注意,这有一些含义。最重要的一点是,类不知道成员是否隐藏在子类中,这意味着转换到基类的子类将始终运行基类功能。请参见以下代码示例以进行说明
public class Base
{
public void Do()
{
Console.WriteLine("Base");
}
}
public class Sub : Base
{
public new void Do()
{
Console.WriteLine("Sub");
}
}
public class Program
{
public static void Main(string[] args)
{
Sub sub = new Sub();
Base base = sub;
sub.Do(); //prints Sub
base.Do(); //prints Base, even though it is the same object.
}
}
仿制药
另一方面,使用泛型,您可以使用类型参数(示例中为TPlate
)对板材类型进行参数化。这稍微复杂一点,但也是更干净的方法,因为子类化和强制转换没有像方法隐藏这样令人困惑的效果
abstract class MyPart<TPart>
where TPart : Part //configure a type parameter
{
public TPart modelObject;
...
}
class MyPlate : MyPart<Plate> //TPlate is now of type Plate
{
public ArraList points; // from API
...
}
class Floor : MyPlate
{
...
}
抽象类MyPart
其中TPart:Part//配置类型参数
{
公共TPart模型对象;
...
}
MyPlate类:MyPart//TPlate现在是Plate类型
{
公共列表点;//来自API
...
}
班级楼层:MyPlate
{
...
}
上面的示例不允许MyFloor进一步专门化类型参数,但这也可以实现:
abstract class MyPart<TPart>
where TPart : Part //configure a type parameter and force it to be a subclass of Part
{
public TPart modelObject;
...
}
class MyPlate<TPlate> : MyPart<TPlate>
where TPlate : Plate //force the type parameter to be a subclass of Plate
{
public ArraList points; // from API
...
}
class Floor : MyPlate<Floor> //TType is now Floor
{
...
}
抽象类MyPart
其中TPart:Part//配置一个类型参数,并强制它成为Part的子类
{
公共TPart模型对象;
...
}
类别MyPlate:MyPart
其中TPlate:Plate//强制类型参数为Plate的子类
{
公共列表点;//来自API
...
}
班级楼层:MyPlate//t类型现在为楼层
{
...
}
这实际上是两个问题。关于为什么你的观点不会被删除的部分已经回答了。但为了完整起见,这里是总结:
德尔