我正在为API创建一个插件,并且存在继承问题。有没有办法“自动”向下转换一个在基类中声明的对象,从它继承的类中?
我的班级结构如下:
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.points
:
points = (modelObject as Plate).points;
points = null; // modelObject.points != null
有没有办法将变量声明为对modelObject
的引用,以便可以对它们进行操作?
答案 0 :(得分:2)
这实际上是两个问题。部分,为什么你的积分不会被删除已经得到了回答。但为了完整起见,这里有摘要:
当您致电var points = (modelObject as Plate).points
时,您复制对points
modelObject
对象的引用。使用points = null
,您只需删除(null)对points
的{{1}}的引用,但modelObject
仍会保留对modelObject
的引用。
要删除points
对modelObject
的引用,请致电points
。
但是对于你的主要问题,如何自动向下转换子类中的对象。有两种方法可以实现这一目标。 方法隐藏和泛型:
方法隐藏
Methhides方法或基类的另一个成员,并为名称提供新的含义。这样,您可以为子类成员赋予另一种含义和另一种返回类型。要实现此目的,您应该将modelObject封装在Property中。你的代码是这样的:
(modelObject as Plate).points = null
注意,在子类中使用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
{
...
}
。这使您仍然可以访问基类ModelObject,尽管您已经为ModelObject赋予了新的含义。除了方法重写之外,您保留基类Member,并仅提供具有相同名称的另一含义。
注意,这有一些含义。最重要的一个是,一个类不知道,如果一个成员隐藏在一个子类中,这意味着,一个子类,被转换为基类,将始终运行基类功能。有关说明,请参阅以下代码示例。
base.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.
}
}
)对Plate的类型进行参数化。这稍微复杂一些,但也更简洁,因为子类化和转换没有像方法隐藏这样的混乱效果。
TPlate
以上示例不允许MyFloor进一步专门化Type参数,但这也可以实现:
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
{
...
}
答案 1 :(得分:1)
您正在创建参考的副本。 points = (modelObject as Plate).points;
所以points
和(modelObject as Plate).points
指向相同的记忆。将null
分配给points
时,会清除一个引用。另一个仍然存在。
如果您希望(modelObject as Plate).points;
为空。只需使用:(modelObject as Plate).points = null;
这与投射没有任何关系。
答案 2 :(得分:0)
当您将points
设置为null
时,您将取消名为&#34;&#34;的引用。在范围内,而不是实际变量。如果你真的不想做modelObject.points = null
(你通常只是这样做),你想通过参考来实际操作它。
请参阅https://msdn.microsoft.com/en-us/library/14akc2c7.aspx
那就是说,我不确定为什么你要对这些物品进行低估,因为我们无法在这里看到足够的事情来确定这些物体。