开发者

Find the immediate implemented interfaces on a type

开发者 https://www.devze.com 2022-12-16 01:13 出处:网络
When calling typeof(Bar).GetInterfaces() on the following scenario the method returns IFoo and IBar.

When calling typeof(Bar).GetInterfaces() on the following scenario the method returns IFoo and IBar.

interface IFoo {}

interf开发者_如何学Pythonace IBar : IFoo {}

class Bar : IBar {}

Is there a way that I can find only the immediate interface (IBar) on Bar?


No, there's no such thing as the "immediate" interface in the compiled code. Your class is effectively compiled as:

class Bar : IBar, IFoo { }

and you can't distinguish between the two. The only thing you could do is to check all of them and see whether two or more of the interfaces inherit from each other or not (and even in that case, you can't really check whether the author of the class has explicitly mentioned the base interface in code or not):

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


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


This picks out the interface with the longest inheritance tree.

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

It was enough for my use case.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号