У меня есть набор классов бизнес-логики, которые наследуются от цепочки абстрактных классов. У меня также есть набор классов бизнес-данных, которые наследуют их собственную цепочку абстрактных классов. В обоих случаях мой производный класс (C) наследуется от абстрактного класса (B), который сам наследуется от абстрактного класса (A). (Поэтому C: B и B: A ... обратите внимание, что это соглашение должно продемонстрировать проблему, а не имена, используемые в моей программе).Доступ к элементам свойства производного класса
В изоляции моя цепочка логических классов ведет себя так, как ожидалось. Вызов метода использует правильную базовую или переопределенную реализацию. То же самое касается моих классов данных (новые поля/свойства отображаются на правильном уровне).
Моя проблема заключается в том, чтобы добавить классы данных в качестве свойства логических классов. Базовый абстрактный логический класс (A) должен иметь возможность вызвать некоторые поля в базовом абстрактном классе данных (опять же, A). Однако следующий абстрактный логический класс в цепочке (B) должен будет использовать некоторые поля/свойства на следующем уровне цепи (B). То же самое для производных бетонных типов (C).
Теперь я предположил, что если в моем логическом классе «А» я добавлю свойство для базового абстрактного класса данных, я мог бы использовать это свойство дальше по цепочке (например, в логическом классе «В», который я мог бы использовать this.Data.Variable для доступа к полю «Variable», в котором поле «Variable» реализовано в классе данных «B»). Я обнаружил, что без трансляции я ограничился использованием полей, открытых в базовом абстрактном классе данных во всей цепочке логических классов.
Я нашел несколько полезных советов на этом сайте и пошел по пути использования дженериков. Мне все еще нужно выполнить бросок в базовых логических классах, когда я использую поля в классе данных (но их не нужно использовать при использовании полей в производном классе).
См. Ниже образец моих классов. Я реализовал MethodA в базовом логическом классе (LogicA), чтобы продемонстрировать, где мне нужно использовать для правильного типа данных, чтобы использовать его поля.
abstract class LogicA<T>
{
public T Data { get; set; }
public virtual void MethodA()
{
var data = (DataA)((dynamic)this.Data);
data.FieldA = "T";
}
}
abstract class LogicB<T> : LogicA<T>
{
public virtual void MethodB()
{
}
}
class LogicC : LogicB<DataC>
{
public void MethodC()
{
this.Data.FieldB = "BBB";
}
}
abstract class DataA
{
public string FieldA { get; set; }
}
abstract class DataB : DataA
{
public string FieldB { get; set; }
}
class DataC : DataB
{
public string FieldC { get; set; }
}
При использовании логики класса, я могу выполнить следующие действия без каких-либо проблем:
LogicC logic = new LogicC();
logic.Data = new DataC();
logic.Data.FieldA = "A";
logic.Data.FieldB = "B";
logic.Data.FieldC = "C";
logic.MethodA();
Моя текущая озабоченность в основном ... есть лучший способ снять то, что я пытаюсь достичь? Я вижу, что этот подход является утомительным с кастинг через абстрактные логические классы при использовании полей данных.
Спасибо, именно то, что мне нужно. – camelCase