2015-03-10 3 views
1

Я унаследовал большую базу кода, и я пытаюсь внедрить некоторые новые функции в структуру. В принципе, для того, чтобы сделать это «правильным» способом, мне пришлось бы модифицировать всю структуру структуры. так как я не тот парень, который разработал фреймворк, и я не читаю читателя, так что, вероятно, этого не произойдет (хотя мне действительно очень хотелось бы переделать все с нуля сам).Наследование родового в C#

Так что, чтобы делать то, что я хочу, я пытаюсь реализовать образец декоратора. This answer from maliger предполагает, что то, что я делаю ниже, совершенно верно. Однако моно, похоже, не нравится; он жалуется, что T не может быть получена, когда я объявляю HappyDecorator

Пожалуйста, простите чрезмерно упрощенный пример, но он перевернет точку.

public class HappyObject 
{ 
    public virtual void print() 
    { 
     Console.WriteLine ("I'm happy"); 
    } 
} 

public class VeryHappyObject : HappyObject 
{ 
    public override void print() 
    { 
     Console.WriteLine ("I'm very happy"); 
    } 

    public void LeapForJoy() 
    { 
     Console.WriteLine("Leaping For Joy!"); 
    } 
} 

public class SuperHappyObject : VeryHappyObject 
{  
    public override void print() 
    { 
     Console.WriteLine ("I'm super happy!"); 
    } 

    public void DieOfLaughter() 
    { 
     Console.WriteLine("Me Dead!"); 
    } 
} 

public class HappyDecorator<T> : T where T : HappyObject 
{ 
    public string SpecialFactor { get; set; } 

    public void printMe() 
    { 
     Console.WriteLine (SpecialFactor); 
     print(); 
    } 
} 
class MainClass 
{ 
    public static void Main (string[] args) 
    { 
     HappyDecorator<HappyObject> obj = new HappyDecorator<HappyObject>(); 
     obj.SpecialFactor = Console.ReadLine(); 
     obj.printMe(); 
    } 
} 
+1

Вы получаете ошибку? Или как он не ведет себя так, как ожидалось? – mason

+0

Это не способ следовать образцу декоратора. obj obect должен получить HappyDecorator в своем конструкторе. –

+0

Вы не можете наследовать параметр родового типа, и это именно то, что сообщение об ошибке говорит для вашего образца кода. Какую часть этого вы не понимаете? – MarcinJuraszek

ответ

3

вы набираете HappyDecorator Т, но нет ни одного случая Т использовать внутри этого класса.

public class HappyDecorator<T> where T : HappyObject 
{ 
    private readonly T _instance; 

    public HappyDecorator(T instance) 
    { 
     _instance = instance; 
    } 

    public string SpecialFactor { get; set; } 

    public void printMe() 
    { 
     Console.WriteLine(SpecialFactor); 
     _instance.print(); 
    } 
} 

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

public class HappyDecorator 
{ 
    public string SpecialFactor { get; set; } 

    public void printMe<T>(T instance) where T : HappyObject 
    { 
     Console.WriteLine(SpecialFactor); 
     instance.print(); 
    } 
} 

И позвони, как:

 HappyDecorator obj = new HappyDecorator(); 
     obj.SpecialFactor = Console.ReadLine(); 
     obj.printMe(new HappyObject()); 
+0

'HappyDecorator' наследует' T' в образце кода OPs, так что это сам экземпляр. – MarcinJuraszek

+2

За исключением того, что это неправильный синтаксис и не компилируется. Поэтому, если он наследует HappyObject, тогда в этом случае преимущества дженериков исчезнут. – CRice

+0

@CRice: Точно. – abatishchev

0

Я думаю, что это то, что вы пытаетесь сделать:

public interface IhappyObject 
    { 
     void Print(); 
    } 

    public class HappyObject : IhappyObject 
    { 
     private IhappyObject obj; 

     public HappyObject(IhappyObject obj) 
     { 
      this.obj = obj; 
     } 

     public void Print() 
     { 
      obj.Print(); 
     } 
    } 

    public class VeryHappyObject : IhappyObject 
    { 
     public void Print() 
     { 
      Console.WriteLine("I'm very happy"); 
     } 
    } 

    public class SuperHappyObject : IhappyObject 
    { 
     public void Print() 
     { 
      Console.WriteLine("I'm super happy!"); 
     } 
    } 

    static void Main(string[] args) 
    { 
     HappyObject obj = new HappyObject(new SuperHappyObject()); 
     obj.Print(); 
    } 
+0

eh, не совсем. Причина, по которой я не выбирал традиционный шаблон декоратора, заключается в том, что я хочу избежать использования явно методов упаковки. Конечно, фактический код (я отказываюсь назвать эту мерзость своей собственной работой) гораздо сложнее, чем пример, который я представил. – audiFanatic

+0

Так, например, предположим, что 'VeryHappyObject' и' SuperHappyObject' имеют параметры, не содержащиеся в интерфейсе 'IHappyBbject'. Если я правильно понимаю вашу реализацию, Конкретно, предположим, что у них были методы 'LeapForJoy()' и 'DieOfLaughter()' соответственно (но не оба). Тогда мне нужно будет определить обе эти функции в интерфейсе, что не совсем то, что я хочу сделать, потому что на самом деле эти объекты намного сложнее, чем я их делаю, и это делается настоящий PITA. – audiFanatic

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