2014-11-19 7 views
0

У меня есть набор классов бизнес-логики, которые наследуются от цепочки абстрактных классов. У меня также есть набор классов бизнес-данных, которые наследуют их собственную цепочку абстрактных классов. В обоих случаях мой производный класс (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(); 

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

ответ

0

Просто укажите ограничения для логического класса:

abstract class LogicA<T> 
    where T: DataA 
{ 
    public T Data { get; set; } 

    public virtual void MethodA() 
    { 
     var data = (DataA)((dynamic)this.Data); 
     data.FieldA = "T"; 
    } 
} 

Используйте тот же подход к другим классам в вашем hierarcy.

+0

Спасибо, именно то, что мне нужно. – camelCase

Смежные вопросы