2015-07-01 4 views
0

У меня трудное время с проблемой на C#.Доступ к общему параметру общего параметра?

В проекте, над которым я работаю, есть классы consumable, в которых хранятся данные, и есть классы consumer, которые используют те расходуемые классы.

Я копировал вещь более простым способом, как это:

using System; 
using System.Collections.Generic; 

interface IBase 
{ 
    int x {get;} 
} 

class BaseClass : IBase 
{ 
    public int x {get; set;} 
} 

interface IDerived : IBase 
{ 
    int y {get;} 
} 

class DerivedClass : BaseClass, IDerived 
{ 
    public int y {get; set;} 
} 

interface IConsumer<in T> where T: class, IBase 
{ 
    void Feed(T arg); 
} 

class BaseConsumer : IConsumer<IBase> 
{ 
    public void Feed(IBase arg) 
    { 
     Console.WriteLine(arg.x); 
    } 
} 

class DerivedConsumer : IConsumer<IDerived> 
{ 
    public void Feed(IDerived arg) 
    { 
     Console.WriteLine(arg.y);  
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     List<IConsumer<IDerived>> consumers = new List<IConsumer<IDerived>>(); 
     consumers.Add(new BaseConsumer()); 
     consumers.Add(new DerivedConsumer()); 

     DerivedClass d = new DerivedClass() { x = 3, y = 5}; 

     foreach (IConsumer<IDerived> consumer in consumers) 
      consumer.Feed(d); 
    } 
} 

Это работает совершенно нормально. Тем не менее, я хочу, чтобы некоторые потребители middle, который принимает еще один объект consumer в своем конструкторе (или другом методе), который перенаправляет вызов Feed на объекты. Например:

class MiddleConsumer<T> : IConsumer<T> where T : class, IBase 
{ 
    private IConsumer<T> _consumer; 
    public MiddleConsumer(IConsumer<T> consumer) 
    { 
     _consumer = consumer; 
    } 

    public void Feed(T arg) 
    { 
     _consumer.Feed(arg); 
    } 
} 

И я бы использовать его как это:

consumers.Add(new MiddleConsumer<IBase>(new BaseConsumer()); 
consumers.Add(new MiddleConsumer<IDerived>(new DerivedConsumer()); 

Но я буду использовать MiddleConsumer с другими конкретными Consumer классов, таких как BaseConsumer и DerivedConsumer. Поэтому мне не нужно явно указывать параметр T, он может просто получить его от фактического типа Consumer. Позвольте пояснить. Я хочу иметь что-то вроде этого: (заметьте, это не действует C# код)

class MiddleConsumer<IConsumer<T>> : IConsumer<T> 
{ 
    private IConsumer<T> _consumer; 
    public MiddleConsumer(IConsumer<T> consumer) 
    { 
     _consumer = consumer; 
    } 

    public void Feed(IDerived arg) 
    { 
     _consumer.Feed(arg); 
    } 
} 

Однако -как expected- это не работает из-за наличия что странного общего параметра.

Я хочу, чтобы создать объект MiddleConsumer с Потребителем, который я не знаю, его базовый тип. Я имею в виду, я хочу быть в состоянии сделать это:

consumers.Add(new MiddleConsumer<BaseConsumer>(new BaseConsumer()); 
consumers.Add(new MiddleConsumer<DerivedConsumer>(new DerivedConsumer()); 

Я не хочу, чтобы проверить базовый тип -для ПРИМЕР- BaseConsumer каждый раз, когда я хочу, чтобы использовать его с MiddleConsumer, так как компилятор может просто посмотрите на это, когда я использую Consumer с MiddleConsumer. Обратите внимание, что могут быть десятки разных классов Consumer.

Мой вопрос: Есть ли способ сделать компилятор C# вывести потребляемый тип для MiddleConsumer из его общего параметра?

Благодарим за помощь!

ответ

0

C# не поддерживает определение типа на конструкторах, но то, что вы можете сделать, это передать вызовы к конструкторам через статический метод:

public static class MiddleConsumer 
{ 
    public static MiddleConsumer<T> Create<T>(IConsumer<T> consumer) where T : class, IBase 
    { 
     return new MiddleConsumer<T>(consumer); 
    } 
} 

Теперь вы не должны указывать общий аргумент вообще :

consumers.Add(MiddleConsumer.Create(new BaseConsumer()); 
+0

Видимо, это единственный способ –

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