2009-02-01 6 views
1
public interface IProcessor<T> 
{ 
    void Process(T instance); 
} 


foreach(AbstractType instance in myClass.SomeCollection) 
    OnProcess(instance); 

public void OnProcess<T>(T instance) 
{ 
    IProcessor<T> processor = 
    unityContainer.Resolve<IProcessor<T>>(); 
    processor.Process(instance); 
} 

Проблема с этим кодом является то, что в OnProcess всегда AbstractType, а не конкретный тип экземпляра, который передается. В настоящее время я вижу две возможности.Вызов общий интерфейс

01: Создайте не общий IProcessor и используйте его как базу для IProcessor. Любой разработчик должен будет реализовать как общие, так и не общие методы Process, обычно типизируя и передавая общий метод.

02: Используйте Type.MakeGenericType, чтобы получить IProcessor, разрешите это, а затем используйте отражение, чтобы вызвать метод процесса.

Оба эти подхода чувствуют себя немного «нечистыми». Может ли кто-нибудь подумать о том, как я могу это сделать, не прибегая к этим методам?

Благодаря

Пит

ответ

3

2 будет производительность убийцей (необходимый динамический/relection вызывать, в частности, идет медленно)

1 является общим ответом на эту проблему, особенно с явной реализацией; проблема заключается в том, чтобы получить тип ... единство разрешает запрос с экземпляром Type, а не через дженерики? Если так что-то вроде ниже ... Конечно, вы все равно должны использовать MakeGenericType:

Type intType = typeof(IProcessor<>).MakeGenericType(instanceType); 
IProcessor proc = (IProcessor) IoC.Resolve(intType); 

Где instanceType это возможно через instance.GetType(). По тем же причинам, это может быть полезно подвергать T как Type на IProcessor:

public interface IProcessor 
{ 
    void Process(object instance); 
    Type InstanceType {get;} 
} 
public interface IProcessor<T> : IProcessor 
{ 
    void Process(T instance); 
} 
class SomeClass: IProcessor<int> 
{ 
    public void Process(int instance) 
    { 
     throw new NotImplementedException(); 
    } 
    Type IProcessor.InstanceType {get {return typeof(int);}} 
    void IProcessor.Process(object instance) 
    { 
     Process((int)instance); 
    } 
} 

Конечно, (опционально) базового класса может позволить вам избежать некоторых из этого в-реализации:

abstract class SomeBase<T> : IProcessor<T> 
{ 
    public void Process(T instance) 
    { 
     OnProcess(instance); 
    } 
    Type IProcessor.InstanceType {get {return typeof(T);}} 
    void IProcessor.Process(object instance) 
    { 
     Process((T)instance); 
    } 
    protected abstract void OnProcess(T instance); 
} 
+0

Мне только удалось обойтись, чтобы зайти на этот сайт. Забавно, что ваше предложение SomeBase - это именно то, что я придумал сегодня утром, отправив письмо с г-ном Скитом по теме :-) Спасибо! –

+0

Как пометить ваш ответ как правильный? –

+1

Я думаю, вы нашли его; -p –

0

Если я правильно понимаю вашу проблему, вы хотите, чтобы вызвать процесс, который зависит от 2-х типов (тип процессора, а объект в обработке). Это правильно? Если это так, вы можете использовать шаблон нескольких методов для такого рода проблем. Вот пример:

public interface IProcessor 
{ 
    void Process(IThingToProcess p); // Will call p.ProcessMe() 
    void Process(ThingToProcess1 concreteP); // Called back from ThingToProcess1.ProcessMe 
} 

public interface IThingToProcess 
{ 
    void ProcessMe(IProcessor p); 
} 

public class ThingToProcess1 : IThingToProcess 
{ 
    public void ProcessMe(IProcessor p) { p.Process(this); } 
} 
Смежные вопросы