2015-05-02 2 views
4

ВНИМАНИЕ:Хотя принятый ответ правильный, для тех, кто пытается осуществить это, пожалуйста, см @ комментарий CodesInChaos также. С моей стороны это была плохая идея.запустим несколько общих методы интерфейса на классе через отражение


У меня есть общий интерфейс и класс, который реализует интерфейс н 'число раз:

interface IA<T> 
{ 
    T Foo(); 
} 

class Baz1 { } 
class Baz2 { } 

class Bar : IA<Baz1>, IA<Baz2> 
{ 
    Baz1 Foo() { return new Baz1(); } 
    Baz2 Foo() { return new Baz2(); } 
} 

Как я могу использовать отражение для вызова как Foo методы экземпляра Bar?

У меня уже есть следующий код, чтобы получить определение интерфейса и параметры универсального типа:

class Frobber 
{ 
    void Frob(object frobbee) 
    { 
     var interfaces = frobbee.GetType() 
      .GetInterfaces() 
      .Where(i => i.IsGenericType && 
       i.GetGenericTypeDefinition() == typeof(IA<>).GetGenericTypeDefinition()); 
    } 
} 
+0

В моей конкретной ситуации, вместо 'IA ', у меня есть класс 'Bar', который реализует' IObservable ',' IObservable 'и т. Д. - а также' IObserver ',' IObserver ' и т. Д. - но я не хотел, чтобы облако обсуждения. Может быть, это актуально? –

+0

Хорошо, думая об этом сейчас, что * * действительно актуально, потому что использование прецедента 'IObservable ' (вызов двух разных методов 'Subscribe()' 'Baz') отличается от используемого случая' IObserver '(вызов два разных метода 'Subscribe()' с 'Baz' в качестве аргумента). Итак, давайте просто рассмотрим первое, как в примере кода, который я предоставил. –

+1

Вы уверены, что хотите наследования вместо композиции здесь? – CodesInChaos

ответ

4

Определение:

interface IA<T> 
{ 
    T Foo(); 
} 

class Baz1 { } 
class Baz2 { } 

class Bar : IA<Baz1>, IA<Baz2> 
{ 
    Baz2 IA<Baz2>.Foo() 
    { 
     return new Baz2(); 
    } 

    Baz1 IA<Baz1>.Foo() 
    { 
     return new Baz1(); 
    } 
} 

Код:

Bar b = new Bar(); 
    var methods = typeof(Bar).GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IA<>)).Select(i => i.GetMethod("Foo")); 
    foreach(var method in methods) 
    { 
     var invoked = method.Invoke(b, null); // or add params instead of null when needed 
    } 
+1

Спасибо, я забыл о том, чтобы сделать реализации ясными. –

+0

Обратите внимание, что вы должны получать только один или нулевой элементы в 'methods', поэтому' Select', возможно, потребуется заменить более подходящей проверкой FirstOrDefault' +. – SimpleVar

+0

@YoryeNathan вы можете получить несколько объектов 'MethodInfo', и вы это сделаете. Вы не можете использовать FirstOrDefault, который превосходит puropse. – Blim

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