2010-01-13 60 views
5

在以下情况下调用typeof(Bar).GetInterfaces()时,该方法返回IFoo和IBar。在类型中查找直接实现的接口

interface IFoo {}
interface IBar : IFoo {}
class Bar : IBar {}

有没有办法,我可以在酒吧找到只顾眼前接口(IBAR)的方法吗?

+1

为什么你想这样做?这听起来像是你的代码中的设计缺陷;) – 2010-01-13 08:53:37

+0

返回的数组是非确定性的。 – sduplooy 2010-01-13 08:54:53

+0

@Oliver,系统将接口映射到具体类型。问题是另一种类型可能会实现IFoo,但我们不想将IFoo接口与Bar类关联,而是将IBar接口关联。 – sduplooy 2010-01-13 08:59:34

回答

12

不,编译代码中没有“直接”接口这样的事情。您的班级有效编译为:

class Bar : IBar, IFoo { } 

您无法区分这两者。你唯一能做的就是检查它们,看看两个或更多的接口是否相互继承(甚至在这种情况下,你也不能真正检查这个类的作者是否明确提到过在代码或没有基本接口):

static IEnumerable<Type> GetImmediateInterfaces(Type type) 
{ 
    var interfaces = type.GetInterfaces(); 
    var result = new HashSet<Type>(interfaces); 
    foreach (Type i in interfaces) 
     result.ExceptWith(i.GetInterfaces()); 
    return result; 
} 
1
public interface IRoo { } 
public interface ISoo : IRoo { } 
public interface IMoo : ISoo { } 
public interface IGoo : IMoo { } 
public interface IFoo : IGoo { } 
public interface IBar : IFoo { } 
public class Bar : IBar { } 

private void button1_Click(object sender, EventArgs e) { 
    Type[] interfaces = typeof(Bar).GetInterfaces();  
    Type immediateInterface = GetPrimaryInterface(interfaces); 
    // IBar 
} 

public Type GetPrimaryInterface(Type[] interfaces) 
{ 
    if (interfaces.Length == 0) return null; 
    if (interfaces.Length == 1) return interfaces[0]; 

    Dictionary<Type, int> typeScores = new Dictionary<Type, int>(); 
    foreach (Type t in interfaces) 
     typeScores.Add(t, 0); 

    foreach (Type t in interfaces) 
     foreach (Type t1 in interfaces) 
      if (t.IsAssignableFrom(t1)) 
       typeScores[t1]++; 

    Type winner = null; 
    int bestScore = -1; 
    foreach (KeyValuePair<Type, int> pair in typeScores) { 
     if (pair.Value > bestScore) { 
      bestScore = pair.Value; 
      winner = pair.Key; 
     } 
    } 
    return winner; 
} 
+0

有趣的代码,但为什么'GetPrimaryInterface'只返回一种接口类型?似乎它需要潜在地返回多种接口类型才能有用。 – HappyNomad 2016-08-23 02:47:17

0

此挑选出具有最长继承树的接口。

typeof(Bar) 
    .GetInterfaces() 
    .OrderByDescending(i => i.GetInterfaces().Length) 
    .FirstOrDefault() 

这足以满足我的用例。