2015-05-02 157 views
4

警告:虽然接受的答案是正确的,任何人试图实现这一点,请参阅@ CodesInChaos的意见为好。对我来说这是一个坏主意。调用多个通用接口的类通过反射方式


我有一个通用的接口和实现的时间接口“N”数字类:

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(); } 
} 

如何使用反射来调用上的Bar实例都Foo的方法呢?

我已经有下面的代码来获取接口定义和泛型类型参数:

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 '用例(在Baz上调用两个不同的'Subscribe()'方法)不同于'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