【问题标题】:c# conditionally continue according base class behaviourc#根据基类行为有条件地继续
【发布时间】:2016-05-31 16:30:51
【问题描述】:
public class A
{
    public A()
    {
        // DoSomething
        // If something is not correct return null;
    }
}

public class B : A
{
    public B() :base()
    {
        // Check if everything was fine in base class
    }
}

如何在这里检查基类是否返回 null 或者它是否完成了他的工作?然后据此,我想停止被实例化?

谢谢。

【问题讨论】:

  • 如果某些东西不能正常工作,那就是错误,所以你应该使用 try-catch 语句

标签: c# class inheritance instantiation base


【解决方案1】:

我建议使用 工厂方法 而不是构造函数:

public class A
{
    protected A()
    {
        ...
    }

    protected Boolean IsCorrect() {...}

    public static A Create() {
      result A = new A();

      if (!IsCorrect())     
        return null;
      else
        return result;
    }
}

public class B : A
{
    protected B() :base()
    {
       ...        
    }

    public static B Create() { 
      result B = new B();

      if (!IsCorrect())     
        return null;
      else
        return result; 
    }
}

....

  B value = B.Create(); // instance of B or null

【讨论】:

    【解决方案2】:

    构造函数不能失败,因此它不能返回null

    您可以考虑使用try-catchthrow,或者根据您的初始化在base class 中创建一个标志,即truefalse,就像这样。

    public class A
    {
        public bool IsInitializationOk; //by default, this is false
        public A()
        {
            // DoSomething
            if(something is not correct)
                return;
            IsInitializationOk = true;
        }
    }
    
    public class B : A
    {
        public B() :base()
        {
            // Check if everything was fine in base class
            if (IsInitializationOk){
                //Do something.
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      如何在这里检查基类是否返回 null 或者它已经完成了他的工作?

      构造函数不返回任何东西。构造函数的目的是使您的对象进入初始化状态,以便可以使用它。

      真正的问题是如果基类中的初始化失败,我应该如何向任何派生类发出信号,并且有很多答案取决于上下文 IMO。

      如果DoStuff 是关键任务并且必须为该对象层次结构工作,那么抛出异常是处理此问题的正确方法,因为您不能真正使用该对象。

      如果DoStuff 是“很高兴拥有”,但对于处理对象并不重要,您可以简单地保留一个受保护的bool 信号失败或成功:

      public class A
      {
          protected bool wasSuccessfull;
          public A()
          {
              wasSuccessfull = DoStuff();
          }
      
          public bool DoStuff() => true;
      }
      
      public class B : A
      {
          public B()
          {
              if (wasSuccessfull) 
                  Console.WriteLine("yay");
          }
      }
      

      我通常会尽量避免在对象的构造函数中进行繁重的工作。如果您有长时间运行的操作,我通常喜欢记录并公开Initialize 方法。当我创建一个新对象时,我希望它尽快提供给调用者,避免任何潜在的长时间挂起,例如连接到数据库。

      【讨论】:

      • 如果DoStuff 只是“nice-to-have”,它不应该转到构造函数 IMO,而是转到可能会或可能不会被适当调用的方法。
      • 阅读我的最后一段,这或多或少是我所说的。如果这是我的决定,我也会这样做。我只是在这里列出可能性,因为我不确定一个是否真的比另一个“更好”。
      • 确实我没有正确阅读。为多种可能性 +1。
      【解决方案4】:

      构造函数不返回任何内容(构造的实例除外)。因此,您无法检查它是否返回null。但是,您可能会在基类构造函数中抛出异常,这表明发生了错误。话虽如此,您不需要检查您的构造函数是否返回任何实例,并假设只要没有引发异常,它就可以正确完成工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-09
        • 1970-01-01
        • 2021-06-10
        • 2021-12-20
        • 2023-01-20
        • 2021-02-28
        • 2018-08-04
        相关资源
        最近更新 更多