【问题标题】:Array of derived classes, calling methods?派生类数组,调用方法?
【发布时间】:2012-09-04 22:59:48
【问题描述】:

所以我有一个 Account 类型的数组,它由从 Account 派生的 Savings 和 Checking 组成。是否有可能让这些调用他们的方法?编译器只使基类中的方法可见,我无法访问派生类中的方法。把我的头撞到这里的墙上。

【问题讨论】:

  • 你能更详细地描述你想要做什么吗?您是否已经知道哪些项目是Savings,哪些是Checking?你不能使用在每种类型中实现不同的虚拟方法吗?
  • 如果帐户不同,并且您必须在代码中使用这种差异(即使用类型为Checking 的元素与类型为Savings 的元素不同),那么不要将它们放在同一个数组。

标签: c# arrays methods base derived


【解决方案1】:

您需要将数组中的元素强制转换为派生类:

((Checking)someArray[42]).Whatever();

如果实例实际上不是该类型,则会抛出 InvalidCastException

【讨论】:

  • 谢谢,我之前尝试过强制转换,但没有放外括号,只在强制转换周围。谢谢!
【解决方案2】:

虽然你可以使用强制转换,但由于你不知道数组元素的确切类型,这会导致一堆异常和一个相当丑陋的代码来处理它们。

你可以使用类似的东西:

Saving s = array[i] as Saving;
if(s != null)
{
   s.SomeSavingMethod();
}
else
{
   Checking c = array[i] as Checking;
   if(c != null)
      c.SomeCheckingMethod();
}

然而,猜测类型并相应地调用方法,通常被认为是一个糟糕的设计。 这听起来像是虚拟方法的情况,或者这些东西一开始就不应该在同一个数组中。

【讨论】:

  • 我是一名学生,教授要求将不同的派生对象放在同一个数组中。这样做的唯一原因!
【解决方案3】:

基本上有两种方法可以用来完成您正在寻找的功能。

第一个并且可以说是最好的(对于您描述的情况)是声明所有这些类都实现的公共接口。

public interface IWorker
{
    void DoWork();
}

public class A : IWorker
{
    public void DoWork()
    {
        // TODO: Implement this method
        throw new NotImplementedException();
    }
}

public class B : IWorker
{
    public void DoWork()
    {
        // TODO: Implement this method
        throw new NotImplementedException();
    }
}

第二个是检测类型并在它支持时调用方法。沿着这些思路。这就是AS operator 非常方便的地方,因为它只会在转换成功时返回非空值。

List<object> workers = new List<object>() { new A(), new B() };
foreach (object itm in workers)
{
    ClassThatSupportsDoWork obj = itm as ClassThatSupportsDoWork;
    if (obj != null)
        obj.DoWork();
}

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 2014-09-05
    • 1970-01-01
    • 2013-12-26
    相关资源
    最近更新 更多