C# 调用基构造函数时重用初始值设定项方法

C# 调用基构造函数时重用初始值设定项方法,c#,oop,constructor,C#,Oop,Constructor,我想使用构造函数初始化派生类中的受保护成员,但由于我调用base(),因此无法调用this(),这会使我的一些调用“有味道”: 有没有一种方法可以避免在每个构造函数中调用InitParam3()。我完全愿意接受设计变更。对子类使用构造函数链,然后调用基类中最完整的构造函数 public class ABase { public object Param1 { get; set; } public object Param2

我想使用构造函数初始化派生类中的受保护成员,但由于我调用base(),因此无法调用this(),这会使我的一些调用“有味道”:


有没有一种方法可以避免在每个构造函数中调用
InitParam3()
。我完全愿意接受设计变更。

对子类使用构造函数链,然后调用基类中最完整的构造函数

    public class ABase
        {
            public object Param1 { get; set; }
            public object Param2 { get; set; }
            protected object Param3 { get; set; }

            public ABase()
                : this(null, null)
            { }

            public ABase(object param1)
                : this(param1, null)
            { }

            public ABase(object param1, object param2)
            {
                Param1 = param1;
                Param2 = param2;
            }
        }

        public class A : ABase
        {
            public A() : this(null, null)
            { }

            public A(object param1)
                : this(param1m, null)
            { }

            public A(object param1, object param2)
                : base(param1, param2)
            { InitParam3(); }

            private void InitParam3()
            {
                Param3 = "param3";
            }
        }
更新(删除默认值的重复):


对子类使用构造函数链,然后调用基类中最完整的构造函数

    public class ABase
        {
            public object Param1 { get; set; }
            public object Param2 { get; set; }
            protected object Param3 { get; set; }

            public ABase()
                : this(null, null)
            { }

            public ABase(object param1)
                : this(param1, null)
            { }

            public ABase(object param1, object param2)
            {
                Param1 = param1;
                Param2 = param2;
            }
        }

        public class A : ABase
        {
            public A() : this(null, null)
            { }

            public A(object param1)
                : this(param1m, null)
            { }

            public A(object param1, object param2)
                : base(param1, param2)
            { InitParam3(); }

            private void InitParam3()
            {
                Param3 = "param3";
            }
        }
更新(删除默认值的重复):

没有

这是一个不错的解决方案

lazyberezovsky方法的问题是,派生类对参数的默认值做出自己的假设,而它必须将其留给超级类

Super类使用null来初始化,如果您更改了使用null以外的其他默认值的决定,则必须更改2个位置

对我来说,决定默认值比微小的重复更重要。

这是一个不错的解决方案

lazyberezovsky方法的问题是,派生类对参数的默认值做出自己的假设,而它必须将其留给超级类

Super类使用null来初始化,如果您更改了使用null以外的其他默认值的决定,则必须更改2个位置


对我来说,对默认值的决定比微小的重复更重要。

这种方法的问题是,派生类做出了与超级类相同的假设,而它必须将其留给超级类。Super class使用
null
进行初始化,如果您更改决定使用除
null
之外的其他默认值,则必须更改2个位置。是的,但这是删除受保护参数初始化重复的唯一方法。其他解决方案是在基本构造函数中调用虚拟初始值设定项,但这是最糟糕的解决方案,因为重写的初始值设定项可能引用一些尚未初始化的子类字段。我认为您应该始终使用
this
链接公共构造函数,并使用单个构造函数调用基类。它保证了构造器之间行为的一致性,并使其更易于维护。重复总是可以删除的。我为默认值添加了常量,并添加了新的c#4功能来生成构造函数链。这种方法的问题是派生类做出了与超级类相同的假设,而它必须将其留给超级类。Super class使用
null
进行初始化,如果您更改决定使用除
null
之外的其他默认值,则必须更改2个位置。是的,但这是删除受保护参数初始化重复的唯一方法。其他解决方案是在基本构造函数中调用虚拟初始值设定项,但这是最糟糕的解决方案,因为重写的初始值设定项可能引用一些尚未初始化的子类字段。我认为您应该始终使用
this
链接公共构造函数,并使用单个构造函数调用基类。它保证了构造器之间行为的一致性,并使其更易于维护。重复总是可以删除的。我已经为默认值添加了常量和新的c#4特性来生成构造函数链。当前的解决方案(您的代码)比@lazyberezovsky answer更好。请参阅我的评论。问题指出“是否有办法避免在每个构造函数中调用InitParam3()”。我实际上必须同意你们两人的意见,但每个解决方案都有自己的缺点。请参阅我的更新解决方案,没有默认值重复。当前解决方案(您的代码)比@lazyberezovsky answer更好。请参阅我的评论。问题陈述为“是否有办法避免在每个构造函数中调用InitParam3()”。实际上,我必须同意你们两位的意见,但每个解决方案都有自己的缺点。请参阅我更新的解决方案,无默认值重复。
public abstract class ABase
{
    protected const object DefaultParam1 = null;
    protected const object DefaultParam2 = null;

    public object Param1 {get;set;}
    public object Param2 { get; set; }
    protected object Param3 { get; set; }

    public ABase(object param1 = DefaultParam1, object param2 = DefaultParam2)
    {
        Param1 = param1;
        Param2 = param2;
    }
}

public class A : ABase
{
    public A(object param1 = DefaultParam1, object param2 = DefaultParam2)
        : base(param1, param2)
    {
        Param3 = "param3";
    }       
}