Trouver les interfaces immédiatement implémentées sur un type

Lors de l’appel de typeof (Bar) .GetInterfaces () sur le scénario suivant, la méthode retourne IFoo et IBar.

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

Existe-t-il un moyen de ne trouver que l’interface immédiate (IBar) sur Bar?

Non, l’interface “immédiate” n’existe pas dans le code compilé. Votre classe est effectivement compilée comme:

 class Bar : IBar, IFoo { } 

et vous ne pouvez pas distinguer les deux. La seule chose que vous puissiez faire est de les vérifier toutes et de voir si deux ou plusieurs interfaces héritent l’une de l’autre ou non (et même dans ce cas, vous ne pouvez pas vraiment vérifier si l’auteur de la classe a explicitement mentionné le interface de base en code ou non):

 static IEnumerable GetImmediateInterfaces(Type type) { var interfaces = type.GetInterfaces(); var result = new HashSet(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 typeScores = new Dictionary(); 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 pair in typeScores) { if (pair.Value > bestScore) { bestScore = pair.Value; winner = pair.Key; } } return winner; } 

Ceci sélectionne l’interface avec le plus long arbre d’inheritance.

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

C’était suffisant pour mon cas d’utilisation.