【问题标题】:Is it possible to have a constructor in a derived class also fire code in the base class' constructor?派生类中的构造函数是否可以在基类的构造函数中触发代码?
【发布时间】:2017-05-25 08:17:49
【问题描述】:

我只是想知道,我目前正在用 C# 为博客站点编写数据模型,并且我正在使用派生类。但烦人的是,我必须在派生类的构造函数中初始化基类的字段,如下所示:

public class baseClass
{
  public dateTime dateCreated { get; protected set; } //only protected because that's what I need...
}

public class derivedClas : baseClass
{
  public derivedClass
  {
    this.dateCreated = DateTime.Now;
  }
}

所以我想做的不是在派生类中手动设置字段,而是在创建派生类的新实例时自动在基类中设置它。这可能吗?

【问题讨论】:

  • 那么当您在填充这些属性的基类中创建构造函数时发生了什么?
  • 顺便说一句,在 SO 中遵循 .NET 命名约定就像在产品代码中一样......
  • @JonSkeet 好的,谢谢,我的惯例是裤子,但我有务实的程序员躺在某个地方......
  • @Servy 我还没有尝试过,但我从你的评论中猜测它会起作用吗?
  • @RhysO 你为什么还要问我,而不是尝试呢?

标签: c# constructor data-manipulation derived-class base-class


【解决方案1】:

如果您在基类中实现与派生类具有匹配签名(相同参数类型)的构造函数,则将自动调用基构造函数。

public class BaseClass
{
    public DateTime DateCreated { get; protected set; } //only protected because that's what I need...

    public BaseClass()
    {
        DateCreated = DateTime.Now;
    }

}

public class DerivedClass : BaseClass
{
    public DerivedClass()
    {
    }
}

【讨论】:

  • 谢谢,但这不是我想做的。我希望能够省略派生类构造函数的初始化,因此它会自动设置为 baseClass 构造函数中的预定义值
  • 看看我的编辑。显然我最初的回答不够清楚。
  • 如果未指定,基本构造函数调用是隐式的,空构造函数体也是如此。派生类中不需要任何代码。
  • @maccettura 现在您有一个不应该存在的构造函数,因为该问题明确指出不应公开设置此值,并且您还错误地复制了日期(通过丢失时间和时区信息)。
  • 这个例子不是真实世界。我试图尽可能多地保留他们的代码。我想让我的答案具有主题性,以便 OP 有上下文答案。如果我只是添加/删除代码,它会满足更多用户吗?
【解决方案2】:

这是您希望实现的目标吗?

void Main()
{
    var i = new B();
    i.Time.Dump();
}

// Define other methods and classes here
public class A
{
    public A()
    {
        Time = DateTime.Now;
    }
    public DateTime Time {get;set;}
}

public class B : A
{
    public B() : base()
    {

    }
}

【讨论】:

    【解决方案3】:

    这应该对你有用:

    public class baseClass
    {
      public dateTime dateCreated { get; protected set; } 
      protected baseClass() {
        dateCreated = DateTime.Now;
      }
    }
    
    public class derivedClas : baseClass
    {
      public derivedClass() : base()
      {
       //Do some constructor stuff for derivedClass if needed
      }
    }
    

    this 将在派生类中的构造函数之前调用基类中的构造函数。

    或者,如果您只想要日期的默认值,您可以这样做:

    public class baseClass
    {
      private DateTime _date = DateTime.Now;
      public DateTime dateCreated { get {return _date;} protected set { _date = value;} } 
    
    }
    

    这应该设置派生类实例化的日期。

    【讨论】:

      【解决方案4】:

      不幸的是,DateTime.Now 不是编译时常量,或者我们可以在这里使用它作为默认值。相反,我们不需要在基类中使用自动实现的属性。这让我们的字段实际上是一个可以为空的类型,所以我们可以通过检查它的值来初始化它,而不需要NullReferenceException

       public class BaseClass
          {      
            private DateTime? _dc;  //notice, it's nullable
            public DateTime DateCreated 
                {
                    get 
                    {
                       if(_dc == null)
                          _dc = InitDate();
                       return (DateTime)_dc;
                    }
                    set
                    { _dc = value; }
      
                }
             private static DateTime InitDate()
             { return DateTime.Now; }
        }
      
        public class DerivedClass : BaseClass
        {
            public DerivedClass
            {           
            }
        }
      

      如果您不介意默认值等于DateTime.MinValue,则可以使用默认参数。

          public class BaseClass
          {
              public DateTime DateCreated { get; set; } = new DateTime();
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-19
        • 2013-08-21
        • 2018-07-16
        • 2018-07-21
        • 1970-01-01
        • 2021-11-11
        • 2016-12-20
        • 2015-05-28
        相关资源
        最近更新 更多