说我有以下三个类:
家长班:
public class ParentClass {
public void foo() {
Debug.Log("Parent called!");
}
}
第一个儿童班:
public class ChildOne : ParentClass {
public new void foo() {
Debug.Log("Child one called!");
}
}
第二个孩子班:
public class ChildTwo : ParentClass {
public new void foo() {
Debug.Log("Child two called!");
}
}
在第四个类中,我有一个包含多个ChildOne和ChildTwo对象的ArrayList。 ArrayList不包含任何其他类型的对象。
如何访问子对象的foo()函数?
public class Example {
public void someFunction() {
//...
ArrayList children = new ArrayList();
children.add(new ChildOne());
children.add(new ChildTwo());
children[0].foo(); //here I want to call the foo() function of the ChildOne object
children[1].foo(); //here I want to call the foo() function of the ChildTwo object
//...
}
}
转换为ParentClass不起作用,我无法转换为其中一个子类,因为我不知道每个元素的类型。
答案 0 :(得分:6)
如果可以,您可以使用多态而不是隐藏父级的foo函数。
要实现此结果,我们可以转换父类以使foo方法虚拟,以便我们可以在子类中覆盖它:
public class ParentClass {
public virtual void foo() {
Debug.Log("Parent called!");
}
}
然后在子课程中,我们使用覆盖关键字替换新关键字:
public class ChildOne : ParentClass {
public override void foo() {
Debug.Log("Child one called!");
}
}
public class ChildTwo : ParentClass {
public override void foo() {
Debug.Log("Child two called!");
}
}
使用ArrayList,您可以这样调用foo方法:
ArrayList children = new ArrayList();
children.Add(new ChildOne());
(children[0] as ParentClass).foo(); // will display "Child one called!"
请注意,children [0]会返回一个对象。您必须将此对象强制转换为ParentClass才能调用foo方法。
我的最后一个建议是使用List而不是ArrayList。列表是强类型的(您不必投射任何东西)并且因为没有装箱/拆箱而快一点。现在使用ArrayList的原因并不多(如果有的话)。
var children = new List<ParentClass>();
children.Add(new ChildOne());
children[0].foo(); // will display "Child one called!"
答案 1 :(得分:0)
反思:
var child = children[0];
Type childType = child.GetType();
MethodInfo mi = childType.GetMethod("foo");
mi.Invoke(child, new object[]{});
答案 2 :(得分:0)
正如Kinetic所述,最佳解决方案是使ParentClass.foo()
虚拟。但是,如果你不能修改父类,那么你还需要别的东西。
作为反思的替代方案,你可以尝试这样的事情:
foreach (var child in children) {
if (child is ChildOne) {
((ChildOne)child).foo();
} else if (child is ChildTwo) {
((ChildTwo)child).foo();
} else {
// whatever you need to do to handle an unknown child
}
}
正如Noob指出的那样,这对许多儿童班来说可能很笨拙。另一种方法是使用接口,如下所示:
public interface IFoo {
void foo();
}
public class ChildOne : ParentClass, IFoo {
public new void foo() {
Debug.Log("Child one called!");
}
}
public class ChildTwo : ParentClass, IFoo {
public new void foo() {
Debug.Log("Child two called!");
}
}
然后这个:
foreach (var child in children) {
if (child is IFoo) {
((IFoo)child).foo();
} else {
// handle unknown child
}
}