Does C # haben ein Äquivalent zu Scala strukturelle Typisierung?
-
26-09-2019 - |
Frage
In Scala, kann ich definieren Strukturtypen wie folgt:
type Pressable = { def press(): Unit }
Das bedeutet, dass ich eine Funktion oder eine Methode definieren, die als Argument etwas nimmt, das Pressable ist, wie folgt aus:
def foo(i: Pressable) { // etc.
Das Objekt, das ich auf diese Funktion übergeben muss, damit sie eine Methode namens Presse definiert hat (), die die Art Signatur in der Art definiert wird, entspricht - hat keine Argumente, kehrt Unit (Scala Version von void)
.Ich kann sogar den Strukturtyp Inline verwenden:
def foo(i: { def press(): Unit }) { // etc.
Es erlaubt im Grunde der Programmierer alle Vorteile der Ente eingeben zu haben, während immer noch den Vorteil der Kompilierung Typüberprüfung mit.
Does C # haben etwas ähnliches? Ich habe gegoogelt, aber kann nichts finden, aber ich bin nicht mit C # in jeder Tiefe vertraut. Wenn es nicht der Fall, gibt es Pläne, diese hinzufügen?
Lösung
Nein, und keine Pläne, die ich kenne. Nur der Name (und nicht strukturell) Subtypisierung (z Schnittstellen).
(Andere wollen auch sehen
http://en.wikipedia.org/wiki/Nominative_type_system
http://en.wikipedia.org/wiki/Structural_type_system
)
(Ein paar Leute einige exotische Ecke Fällen können darauf hinweisen, wie die foreach
Anweisung strukturelle Typisierung für GetEnumerator
verwenden, aber das ist die Ausnahme eher als die Regel.)
Andere Tipps
Es gibt keine Möglichkeit, Strukturtypen zu definieren, die eine bestimmte Funktion hat. Es gibt eine Bibliothek, die Ente eingeben Unterstützung C # hinzufügt, die hier werden kann.
Dies ist das Beispiel von Duck Typing Projekt. Bitte beachten Sie die Duck Typing zur Laufzeit geschieht und kann scheitern. Es ist zu verstehen, meint auch, dass diese Bibliothek Proxies für die Typen erzeugt, die Ente getippt sind, die weit von der eleganten Kompilierung-Unterstützung weinen wird, die in Scala genossen wird. Dies ist wahrscheinlich so gut wie es mit dieser Generation von C # wird.
public interface ICanAdd
{
int Add(int x, int y);
}
// Note that MyAdder does NOT implement ICanAdd,
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
public int Add(int x, int y)
{
return x + y;
}
}
public class Program
{
void Main()
{
MyAdder myAdder = new MyAdder();
// Even though ICanAdd is not implemented by MyAdder,
// we can duck cast it because it implements all the members:
ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder);
// Now we can call adder as you would any ICanAdd object.
// Transparently, this call is being forwarded to myAdder.
int sum = adder.Add(2, 2);
}
}
Dies ist der C # Weg, um die gleiche Sache zu erreichen, die guten alten langweiligen Schnittstellen.
interface IPressable {
void Press();
}
class Foo {
void Bar(IPressable pressable) {
pressable.Press();
}
}
class Thingy : IPressable, IPushable, etc {
public void Press() {
}
}
static class Program {
public static void Main() {
pressable = new Thingy();
new Foo().Bar(pressable);
}
}
Wie andere bereits erwähnt, ist dies nicht wirklich in .NET (wie dies ist eine Frage der Laufzeit als eine Sprache). Allerdings .NET 4.0 unterstützt ähnliche Sache für importierte COM-Schnittstellen und ich glaube, dass dies für die Durchführung der Struktur Typisierung für .NET verwendet werden könnte. Sehen Sie dieses Blog-Post:
- Faking COM den C # -Compiler zu täuschen
Ich habe nicht versucht, mit diesem zu spielen selbst noch nicht, aber ich denke, es ist Compiler Autoren ermöglichen könnte für .NET-Sprachen mit strukturellen Typisierung zu schreiben. (Die Idee ist, dass Sie (oder ein Compiler) eine Schnittstelle hinter der Szene definieren würden, aber es funktionieren würde, weil die Schnittstellen als gleichwertig dank der COM-Äquivalenz-Funktion behandelt werden würden).
Auch C # 4.0 unterstützt das dynamic
Schlüsselwort, das, glaube ich, als strukturelle Typisierung interpretiert werden könnte (ohne statische Typprüfung). Das Schlüsselwort können Sie Methoden auf jedem Objekt aufrufen, ohne (zum Zeitpunkt der Kompilierung) knowning, ob das Objekt die erforderlichen Methoden. Dies ist im Wesentlichen dasselbe wie das „Duck Typing“ Projekt erwähnt von Igor (aber das ist, natürlich, keine richtige strukturelle Typisierung).
Das awaitable Muster in C # kann vielleicht als beschränkt, Ad-hoc-Instanz strukturellen Subtyping / Existenz Typisierung interpretiert werden. Der Compiler wird nur Objekte await
den Zugriff auf eine GetAwaiter()
Methode, die zurückkehrt jedes INotifyCompletion
Objekt mit einem bestimmten Satz von Methoden und Eigenschaften. Da weder das ‚awaitable‘ Objekt noch die Bedürfnisse Erwartenden 'Objekt jede Schnittstelle (mit Ausnahme INotifyCompletion
im Fall des letzteren) zu implementieren, await
ist ähnlich wie bei einem Verfahren, das awaitable Objekte strukturell getippt akzeptiert.