[c#] Was ist der Zweck einer Marker-Schnittstelle?


Answers

Markierungsschnittstellen werden verwendet, um die Fähigkeit einer Klasse zu kennzeichnen, eine bestimmte Schnittstelle zur Laufzeit zu implementieren.

Das Interface Design und .NET Type Design Guidelines - Interface Design verhindern die Verwendung von Marker Interfaces zugunsten der Verwendung von Attributen in C #, aber wie @Jay Bazuzi herausfindet, ist es einfacher nach Marker Interfaces zu suchen als nach Attributen: o is I

Also statt dessen:

public interface IFooAssignable {} 

public class FooAssignableAttribute : IFooAssignable 
{
    ...
}

Die .NET-Richtlinien empfahlen Ihnen Folgendes:

public class FooAssignableAttribute : Attribute 
{
    ...
}

[FooAssignable]
public class Foo 
{    
   ...
} 
Question

Was ist der Zweck einer Marker-Schnittstelle?




Eine Markierungsschnittstelle ist nur eine Schnittstelle, die leer ist. Eine Klasse würde diese Schnittstelle als Metadaten implementieren, die aus irgendeinem Grund verwendet werden. In C # würden Sie häufiger Attribute verwenden, um eine Klasse aus denselben Gründen zu markieren, aus denen Sie eine Markierungsschnittstelle in anderen Sprachen verwenden würden.




Marker sind leere Schnittstellen. Ein Marker ist entweder da oder nicht.

Klasse Foo: IConfidential

Hier kennzeichnen wir Foo als vertraulich. Keine tatsächlichen zusätzlichen Eigenschaften oder Attribute erforderlich.




Eine Markierungsschnittstelle ermöglicht es, eine Klasse so zu kennzeichnen, dass sie auf alle nachfolgenden Klassen angewendet wird. Eine "reine" Markierungsschnittstelle würde nichts definieren oder erben; Ein nützlicherer Typ von Markierungsschnittstellen kann einer sein, der eine andere Schnittstelle "erbt", aber keine neuen Elemente definiert. Zum Beispiel, wenn es eine Schnittstelle "IReadableFoo" gibt, könnte man auch eine Schnittstelle "IImmutableFoo" definieren, die sich wie ein "Foo" verhält, aber jedem, der es benutzt, versprechen würde, dass nichts seinen Wert ändern würde. Eine Routine, die ein IImmutableFoo akzeptiert, könnte es genauso verwenden wie IReadableFoo, aber die Routine würde nur Klassen akzeptieren, die als Implementieren von IImmutableFoo deklariert wurden.

Ich kann mir nicht viele Anwendungen für "reine" Markierschnittstellen vorstellen. Der einzige, den ich mir vorstellen kann, wäre, wenn EqualityComparer (of T) .Default Object.Equals für jeden Typ zurückgibt, der IDoNotUseEqualityComparer implementiert hat, selbst wenn der Typ auch IEqualityComparer implementiert hat. Dies würde es ermöglichen, einen unverschlossenen unveränderlichen Typ zu haben, ohne gegen das Liskov-Substitutionsprinzip zu verstoßen: Wenn der Typ alle Methoden im Zusammenhang mit Gleichheitsprüfung versiegelt, könnte ein abgeleiteter Typ zusätzliche Felder hinzufügen und sie veränderbar machen, aber die Mutation solcher Felder würde nicht t mit allen Basistyp-Methoden sichtbar sein. Es mag nicht schrecklich sein, eine unverschlossene unveränderliche Klasse zu haben und entweder die Verwendung von EqualityComparer.Default oder von Trust abgeleiteten Klassen zu vermeiden, um IEqualityComparer nicht zu implementieren, aber eine abgeleitete Klasse, die IEqualityComparer implementiert hat, könnte als änderbare Klasse erscheinen, selbst wenn sie als Basis betrachtet wird. Klassenobjekt.




Related