2010-01-13 5 views
5

Beim Aufrufen von Typeof (Bar) .GetInterfaces() für das folgende Szenario die Methode gibt IFoo und IBar zurück.Suchen Sie die sofort implementierten Schnittstellen auf einem Typ

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

Gibt es eine Möglichkeit, dass ich nur die unmittelbare Schnittstelle (IBar) auf Bar finden kann?

+1

Warum möchten Sie das tun? Es klingt für mich wie ein Designfehler in Ihrem Code;) –

+0

Das zurückgegebene Array ist nicht deterministisch. – sduplooy

+0

@Oliver, das System bildet Schnittstellen zu konkreten Typen ab. Das Problem ist, dass ein anderer Typ IFoo implementiert, aber wir möchten die IFoo-Schnittstelle nicht mit der Bar-Klasse, sondern mit der IBar-Schnittstelle verknüpfen. – sduplooy

Antwort

12

Nein, es gibt keine "unmittelbare" Schnittstelle im kompilierten Code. Ihre Klasse ist effektiv kompiliert als:

class Bar : IBar, IFoo { } 

und Sie können nicht zwischen den beiden unterscheiden. Das einzige, was Sie tun könnten, ist, alle zu überprüfen und zu sehen, ob zwei oder mehr der Interfaces von einander erben oder nicht (und selbst in diesem Fall können Sie nicht wirklich überprüfen, ob der Autor der Klasse die. Explizit erwähnt hat) Basisschnittstelle in Code oder nicht):

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

Interessanter Code, aber warum gibt 'GetPrimaryInterface' nur einen Schnittstellentyp zurück? Es scheint, dass mehrere Schnittstellentypen möglicherweise zurückgegeben werden müssen, um nützlich zu sein. – HappyNomad

0

Dies nimmt die Schnittstelle mit dem längsten Vererbungsbaum aus.

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

Es war genug für meinen Anwendungsfall.

Verwandte Themen