在类型上查找立即实现的接口

时间:2010-01-13 08:47:01

标签: c# reflection

在以下场景中调用typeof(Bar).GetInterfaces()时,该方法返回IFoo和IBar。

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

有没有办法可以在Bar上找到直接界面(IBar)?

3 个答案:

答案 0 :(得分:13)

不,编译代码中没有“立即”界面。您的课程有效编译为:

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 :(得分: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;
}

答案 2 :(得分:0)

这将选择具有最长继承树的接口。

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

这对我的用例来说已经足够了。