2013-06-25 4 views
2

я в настоящее время есть небольшая иерархия объектов, который выглядит следующим образом:Generic базового класса с несколькими детьми

public class BaseClass { 
    // this class is empty and exists only so the others can extend it and share the 
    // same base type 
} 

public class ChildA : BaseClass { 
    public Subject<AssociatedClassA> Results; 
} 

public class ChildB : BaseClass { 
    public Subject<AssociatedClassB> Results; 
} 

В моей конструкции я хотел бы применять, что каждый класс, который простирается от BaseClass должен содержать Subject<SomeType> называется Results. Мне интересно, есть ли способ переносить результаты в базовый класс или интерфейс, чтобы я мог предоставить общий тип для Subject при построении базового класса. Например, было бы удивительным, если бы я мог сделать что-то вроде этого:

ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>(); 

или даже лучше, так как там действительно должны быть только один параметр шаблона, который соответствует с childâ, если когда я построил его, что можно было бы позаботиться о для я:

ChildA instance = new ChildA(); 
// Results is automatically set to Subject<AssociatedClassA> 

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

Следуя рекомендациям ниже, это решает мое желание перенести результаты в базовый класс, однако я столкнулся с другой проблемой в том, что я надеялся использовать BaseClass в качестве общего параметра для таких методов, как что можно использовать любой из производных классов. Например:

public void ProcessBaseClass(BaseClass base) { 
    // base could be ChildA or ChildB here 
} 

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

ответ

6

В случае необходимости, вы можете сделать родительский родовое:

public class BaseClass<T> { 
    public Subject<T> Results; 
} 

public class ChildA : BaseClass<AssociatedClassA> { 
} 

public class ChildB : BaseClass<AssociatedClassB> { 
} 
+0

Спасибо, это именно то, что я искал. –

+0

Если у вас есть какие-то соображения относительно Edit I, сделанного в оригинальном посте? –

+1

@JesseCarter: В зависимости от ситуации вы можете сделать это 'ProcessBaseClass ()' или сделать 'BaseClass ' наследовать от 'BaseClass'. Или сделайте интерфейс. – Ryan

4

Вы можете сделать сам базовый класс родовое:

public class BaseClass<T> { 
    public T Results { get; protected set; } 
} 
+3

@Jesse В дополнение к этому, если ваш 'типы AssociatedClass' также в иерархии типов вы можете иметь общее ограничение для вашего базового класса: «BaseClass , где T: BaseAssociatedClass {}', что позволяет проследить некоторые базовые поведения. –