Базовое наследование — слишком подробное?

#c# #inheritance #constructor

#c# #наследование #конструктор

Вопрос:

Я ищу программно более разумный способ наследования здесь. Я очень новичок в мире программирования, поэтому здесь я ищу больше методологии. Это правильный способ наследования?

Базовый класс в этом случае имеет большой конструктор. Необходимость вызова base(w, x, y, z) в каждом унаследованном классе выглядит невероятно подробным. Честно говоря, это выглядит как ленивый или плохой код.

 public class DataStudioGear : DataItem  {
    string name;

    int moneyValue;
    int compression;
    int wideness;
    int wowFactor;

    public DataStudioGear(string name, int value, int comp, int wide, int wow) {
        this.name = name;
        moneyValue = value;
        compression = comp;
        wideness = wide;
        wowFactor = wow;
    }
}
  

Итак, теперь любой класс, который наследует от этого, должен, конечно, передавать эти переменные конструктору. Это оставляет меня с кучей классов, которые выглядят так:

 public class Console : DataStudioGear {
    public Console(string name, int value, int comp, int wide, int wow) : base(name, value, comp, wide, wow) {

    }
}

public class Compressor : DataStudioGear {
    public Compressor(string name, int value, int comp, int wide, int wow) : base(name, value, comp, wide, wow) {

    }
}
  

Эти конструкторы огромны. Хотя я очень новичок в программировании в целом, это просто выглядит как плохой код.

Есть ли лучшее решение для того, чего я пытаюсь достичь здесь?

Комментарии:

1. Ваш код правильный, afaik, нет лучшего способа написать его, хотя я согласен с вами, что он выглядит неуклюжим

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

3. Следует также отметить, что если конструктор принимает параметры, которые могут быть снабжены значением по умолчанию на основе производного типа, вы можете жестко запрограммировать значение в base constructor и исключить его из вашего производного конструктора.

4. Если некоторые из этих свойств не всегда необходимы, и объект может функционировать без них, вы можете удалить их из конструктора и установить с помощью создания экземпляра объекта: new Foo(x, y) { ZProperty = z};

Ответ №1:

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

 public class DataStudioGear : DataItem
{
    string _name;
    private int _moneyValue;
    int _compression;
    int _wideness;
    int _wowFactor;

    public static T DataTestFactory<T>(string name, int value, int comp, int wide, int wow)
        where T : DataStudioGear, new()
    {
        return new T { _name = name, _moneyValue = value, _compression = comp, _wideness = wide, _wowFactor = wow};
    }
}

public class Console : DataStudioGear { }

public class Compressor : DataStudioGear { }

[TestMethod]
public void TestDataItemFactory()
{
    Console console = DataStudioGear.DataTestFactory<Console>("test", 1, 1, 1, 1);
    Compressor compressor = DataStudioGear.DataTestFactory<Compressor>("test", 1, 1, 1, 1);
}
  

Комментарии:

1. Это тот, мой друг! Ты потрясающий! Я почти спросил, были ли дженерики ответом, поскольку я подозревал, что они могут быть полезны здесь!

2. О, привет, какое пространство имен вы используете для этого модного модульного теста?

3. Ваши подозрения были верны. Рад помочь! Я использую Microsoft.VisualStudio. Тестовые инструменты. UnitTesting. Это можно так же легко заменить с помощью NUnit, просто измените TestMethod на Test .