712 Stimmen

Wie man bestimmt, ob ein Typ eine Schnittstelle mit C#-Reflexion implementiert

Bietet Reflexion in C# eine Möglichkeit festzustellen, ob ein bestimmter System.Type ein bestimmtes Interface modelliert?

public interface IMyInterface {}

public class MyType : IMyInterface {}

// sollte 'true' ergeben
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);

1234voto

Jeff Punkte 34377

Sie haben ein paar Möglichkeiten:

  1. typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
  2. typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
  3. Mit C# 6 können Sie typeof(MyType).GetInterface(nameof(IMyInterface)) != null verwenden

Für ein generisches Interface ist es etwas anders.

Array.Exists(typeof(MyType).GetInterfaces(), i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))

84 Stimmen

Bitte beachten Sie, dass typeof(IMyInterface).IsAssignableFrom(typeof(IMyInterface)) ebenfalls wahr ist, was möglicherweise ein unerwartetes Ergebnis für Ihren Code haben könnte.

34 Stimmen

Es war auf jeden Fall einfach, nicht aufzupassen und die Argumente für IsAssignableFrom falsch zu bekommen. Ich werde jetzt mit GetInterfaces gehen :p

18 Stimmen

Die IsAssignableFrom(t1) Variante ist in meinem Code etwa 3x schneller als das GetInterfaces().Contains(t2) Gegenstück.

111voto

Snea Punkte 1737

Verwenden Sie Type.IsAssignableFrom:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType));

36voto

ajma Punkte 11955
typeof(IMyInterface).IsAssignableFrom(someclass.GetType());

oder

typeof(IMyInterface).IsAssignableFrom(typeof(MyType));

46 Stimmen

Wenn Sie bereits eine Instanz der Klasse haben, ist ein viel besserer Ansatz einfach someclass ist IMyInterface , da dies überhaupt keine Reflektionskosten mit sich bringt. Also, obwohl es nicht falsch ist, ist es nicht der ideale Weg, es zu tun.

2 Stimmen

@James - Ja, sogar Resharper gibt die gleiche Empfehlung.

0 Stimmen

@JamesJ.ReganIV du solltest das als Antwort posten, ich hätte deinen Kommentar fast übersehen

26voto

olabacker Punkte 814

Verwenden Sie Type.IsAssignableTo (ab .NET 5.0):

typeof(MeinTyp).IsAssignableTo(typeof(IMyInterface));

Wie in einigen Kommentaren erwähnt, kann IsAssignableFrom als "verwirrend" angesehen werden, da es "rückwärts" ist.

0 Stimmen

Dies erfasst auch Basisklassen sowie Schnittstellen (gut für mich :))

15voto

Panos Theof Punkte 1433
public static bool ImplementsInterface(this Type type, Type ifaceType)
{
    Type[] intf = type.GetInterfaces();
    for(int i = 0; i < intf.Length; i++)
    {
        if(intf[i] == ifaceType)
        {
            return true;
        }
    }
    return false;
}

Ich denke, das ist die richtige Version, aus drei Gründen:

  1. Es verwendet GetInterfaces und nicht IsAssignableFrom, was schneller ist, da IsAssignableFrom letztendlich nach mehreren Überprüfungen GetInterfaces aufruft.
  2. Es iteriert über das lokale Array, daher wird es keine Grenzüberprüfungen geben.
  3. Es verwendet den == Operator, der für Type definiert ist, daher ist er wahrscheinlich sicherer als die Equals Methode (die der Contains Aufruf letztendlich verwenden wird).

10 Stimmen

+1 für den Inhalt, ich mag die Leerzeichen um die Klammern und die ägyptischen Klammern jedoch nicht. Auch die ganze Methode kann so geschrieben werden: return type.GetInterfaces().Any(t => t == ifaceType);

1 Stimmen

Type.IsAssignableFrom() wirkt intern genauso wie Ihr Code.

1 Stimmen

Auch warum nicht type.GetInterfaces().Contains(ifaceType) verwenden, das kein LINQ verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X