Как я должен связать конструкторы в иерархии классов? - PullRequest
7 голосов
/ 11 августа 2011

У нас есть следующая иерархия классов:

public class Base
{
    public Base()
    {
        // do generic initialization 
    }

    public Base(SomeClass param1) : this()
    {
        // init properties that require param1
    }

    public Base(SomeClass param1, OtherClass param2) : this(param1)
    {
        // init properties that require param2
    }

    // ...
}

public class Derived : Base
{
    public Derived()
    {
        // do custom initialization 
    }

    public Derived(SomeClass param1) : this() // ???
    {
        // do custom initialization using param1
    }

    public Derived(SomeClass param1, OtherClass param2) : this(param1) // ???
    {
        // do custom initialization using param2
    }

    // ...
}

Нам бы потребовалось Derived, чтобы запустить и свои собственные процедуры инициализации, цепочку вверх и соответствующие из базового класса. Как объединить конструкторы в цепочку, не дублируя код и не запустив несколько конструкторов дважды?

Ответы [ 2 ]

5 голосов
/ 11 августа 2011

В производной цепочке классов конструкторы с наименьшими параметрами по сравнению с конструктором с наибольшим количеством параметров, а затем производный конструктор с наибольшим количеством параметров приковывается к базе. Примерно так:

public class Base 
{
  public Base() : this(null, null)
  {
  }
  public Base(SomeClass param1) : this(param1, null)
  {
  }
  public Base(SomeClass param1, OtherClass param2)
  {
    if (param1 != null)
    {
      // initialise param1
    }
    if (param2 != null)
    {
      // initialise param2
    }
  }
}

public class Derived : Base
{
  public Derived() : this(null, null)
  {
  }
  public Derived(SomeClass param1) : this(param1, null)
  {
  }
  public Derived(SomeClass param1, OtherClass param2) : base(param1, param2)
  {
  }
} 

В зависимости от контекста может быть лучше использовать значение по умолчанию (T) вместо нуля, чтобы указать отсутствующее значение / значение по умолчанию.

3 голосов
/ 11 августа 2011

Как правило, вы связываете конструктор с наименьшим, с тем, у которого больше всего, например:

public Derived(SomeClass param1) : this(param1, param2)
{}

См. Эту статью на Конструкторы в C # для получения дополнительной информации.

Редактировать:

В соответствии с @Scott ниже:

Тогда с наибольшим количеством параметров будет public Derived(SomeClass param1, OtherClass param2) : base(param1, param2), и вы поместите свой код инициализации в конструктор 2 параметров в derived и base

Чтобы продемонстрировать, что все конструкторы вызываются, я составил программу:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class Base
    {
        public Base()
            : this(null, null)
        {
        }
        public Base(string param1)
            : this(param1, null)
        {
        }
        public Base(string param1, string param2)
        {
            Console.WriteLine("Base Class: " + param1 + "+" + param2);

            if (param1 != null)
            {
                // initialise param1
            }
            if (param2 != null)
            {
                // initialise param2
            }
        }
    }

    public class Derived : Base
    {
        public Derived()
            : this("", "")
        {
        }
        public Derived(string param1)
            : this(param1, "")
        {
        }
        public Derived(string param1, string param2)
            : base(param1, param2)
        {
            Console.WriteLine("Derived Class: " + param1 + "+" + param2);
        }
    } 
    class Program
    {
        static void Main(string[] args)
        {
            Derived d = new Derived("test1", "test2");
            Console.ReadLine();
        }
    }
}

Вывод:

Base class: test1+test2
Derived class: test1+test2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...