【问题标题】:How to check whether a base class object or derived object?如何检查是基类对象还是派生对象?
【发布时间】:2012-07-03 14:01:55
【问题描述】:

我有一个BankAccount 课程。 FixedBankAccount 和 SavingsBankAccount 是从它派生的。
如果收到的对象不是派生对象,我需要抛出异常。我有以下代码。

IEnumerable<DBML_Project.BankAccount> accounts = AccountRepository.GetAllAccountsForUser(userId);
foreach (DBML_Project.BankAccount acc in accounts)
{
    string typeResult = Convert.ToString(acc.GetType());
    string baseValue = Convert.ToString(typeof(DBML_Project.BankAccount));

    if (String.Equals(typeResult, baseValue))
    {
        throw new Exception("Not correct derived type");
    }
}

namespace DBML_Project
{

public  partial class BankAccount
{
    // Define the domain behaviors
    public virtual void Freeze()
    {
        // Do nothing
    }
}

public class FixedBankAccount : BankAccount
{
    public override void Freeze()
    {
        this.Status = "FrozenFA";
    }
}

public class SavingsBankAccount : BankAccount
{
    public override void Freeze()
    {
        this.Status = "FrozenSB";
    }
}

} // namespace DBML_Project

还有比这更好的代码吗?

【问题讨论】:

  • 没关系,改成if(acc.getType() == typeof(DBML_Project.BankAccount))
  • 不清楚你想做什么。编译器不会让您或其他任何人向accounts 添加不是从BankAccount 派生的对象,因此您无需检查。
  • @AseemGautam:如果acc 是派生类型,那将返回false。
  • @O.R.Mapper:会吗?抱歉,不知道!
  • @bhuvin 的答案从设计的角度来看是正确的,你不应该首先检查类型。

标签: c# .net oop


【解决方案1】:

你应该使用Type.IsAssignableFrom

if (acc.GetType().IsAssignableFrom(typeof(BankAccount)))
    // base class
else
    // derived

【讨论】:

    【解决方案2】:

    将 BankAccount 类声明为 Abstract。

    【讨论】:

    • 这对这个问题有什么帮助?
    • 它将限制方法的调用者只传递派生类型,根本不需要检查。
    • 哦,现在我明白了他的实际要求……通过阅读问题,他似乎想自己检查类型兼容性。
    • 我无法将基类抽象化。其他一些客户端需要实例化基类
    • @Lijo - 老兄,这种情况下的设计需要扫描。因为在设计上不应该是这样。
    【解决方案3】:

    我会定义一个接口(类似于 IAccettableBankAccount,但您知道自己的域,因此您应该能够找到更好的名称)并让 FixedBankAccount 和 SavingsBankAccount 实现它。那么你的测试就是:

    if (!acc is IAccettableBankAccount)
    {
         throw new Exception("Not correct derived type");
    }
    

    【讨论】:

    • 感谢您的想法。它比我当前的实现更好吗?
    • 视情况而定。当然,它为您提供了更多控制权,即在您的实现中,BankAccount 的每个子类(甚至未来的类)都将始终正常,使用该接口,您可以拥有从 BankAccount 派生的类,但可能会引发异常。
    【解决方案4】:

    使用Type.IsSubclassOf 方法。更多信息请查看this

    foreach (DBML_Project.BankAccount acc in accounts)
    {
        if (!acc.GetType().IsSubclassOf(typeof(DBML_Project.BankAccount))
        {
            throw new Exception("Not correct derived type");
        }
    }
    

    【讨论】:

      【解决方案5】:

      你可以直接检查类型:

          var accounts = AccountRepository.GetAllAccountsForUser(userId);
          if (accounts.Any(acc => acc.GetType() == typeof(DBML_Project.BankAccount))) {
              throw new Exception("Not correct derived type");
          }
      

      将类声明为抽象类也可能有所帮助,但我不知道这是否适合您的情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 2012-09-06
        • 2018-08-18
        • 1970-01-01
        • 1970-01-01
        • 2020-03-12
        • 2020-05-29
        相关资源
        最近更新 更多