Повторное использование метода инициализатора при вызове базового конструктора - PullRequest
1 голос
/ 26 марта 2012

Я хочу инициализировать защищенный член в производном классе, используя конструктор, но так как я вызываю base (), я не могу вызвать this (), что делает некоторые из моих вызовов «запахом»:

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()
        { InitParam3(); }

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

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

        private void InitParam3()
        {
            Param3 = "param3";
        }
    }

Есть ли способ избежать вызова InitParam3() в каждом конструкторе.Я полностью готов к изменениям дизайна.

Ответы [ 2 ]

6 голосов
/ 26 марта 2012

Используйте цепочку конструкторов для дочернего класса и затем вызовите наиболее полный конструктор базового класса.

    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 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";
    }       
}
1 голос
/ 26 марта 2012

номер

Это правильное решение.

Проблема с подходом Лениберезовского состоит в том, что производный класс делает свои собственные предположения о значении параметров по умолчанию, в то время как он должен оставить его для суперкласса.

Супер-класс использует null для инициации, и если вы измените свое решение на использование другого значения по умолчанию, отличного от null, вам придется изменить 2 места.

Для меня решение о значении по умолчанию важнее, чем незначительное дублирование.

...