Gibt es ein typedef-Äquivalent in C # oder eine Möglichkeit, ein ähnliches Verhalten zu erzielen? Ich habe ein bisschen gegoogelt, aber überall, wo ich hinschaue, scheint es negativ zu sein. Derzeit habe ich eine ähnliche Situation wie die folgende:
class GenericClass<T>
{
public event EventHandler<EventData> MyEvent;
public class EventData : EventArgs { /* snip */ }
// ... snip
}
Jetzt braucht ein Raketenwissenschaftler nicht mehr, um herauszufinden, dass dies sehr schnell zu viel Tippen führen kann (Entschuldigung für das schreckliche Wortspiel), wenn er versucht, einen Handler für dieses Ereignis zu implementieren. Es würde ungefähr so aussehen:
GenericClass<int> gcInt = new GenericClass<int>;
gcInt.MyEvent += new EventHandler<GenericClass<int>.EventData>(gcInt_MyEvent);
// ...
private void gcInt_MyEvent(object sender, GenericClass<int>.EventData e)
{
throw new NotImplementedException();
}
Außer in meinem Fall habe ich bereits einen komplexen Typ verwendet, nicht nur einen int. Es wäre schön, wenn es möglich wäre, dies ein wenig zu vereinfachen ...
Bearbeiten: dh. Vielleicht müssen Sie den EventHandler eingeben, anstatt ihn neu definieren zu müssen, um ein ähnliches Verhalten zu erzielen.
using MyClassDictionary = System.Collections.Generic.Dictionary<System.String, MyNamespace.MyClass>;
Ist er korrekt? Ansonsten scheint es die darüber liegendenusing
Definitionen nicht zu berücksichtigen .typedef uint8 myuuid[16];
durch die Direktive "using" konvertieren .using myuuid = Byte[16];
kompiliert nicht.using
kann nur zum Erstellen von Typ- Aliasen verwendet werden.typedef
scheint viel flexibler zu sein, da es einen Alias für eine ganze Deklaration (einschließlich Arraygrößen) erstellen kann. Gibt es in diesem Fall eine Alternative?Jon hat wirklich eine schöne Lösung gegeben, ich wusste nicht, dass du das kannst!
Manchmal habe ich von der Klasse geerbt und ihre Konstruktoren erstellt. Z.B
Nicht die beste Lösung (es sei denn, Ihre Baugruppe wird von anderen Personen verwendet), aber sie funktioniert.
quelle
public class FooList : LikeType<IReadOnlyList<Foo>> { ... }
und dann verwenden , überall würden Sie erwartenIReadOnlyList<Foo>
. Meine Antwort unten zeigt mehr Details.Foo
wenn er an eine Vorlagenmethode übergeben wird, die akzeptiertList<T>
. Mit richtigem typedef wäre es möglich.Wenn Sie wissen, was Sie tun, können Sie eine Klasse mit impliziten Operatoren definieren, die zwischen der Alias-Klasse und der tatsächlichen Klasse konvertiert werden sollen.
Ich unterstütze dies nicht wirklich und habe so etwas noch nie benutzt, aber dies könnte wahrscheinlich unter bestimmten Umständen funktionieren.
quelle
C # unterstützt eine geerbte Kovarianz für Ereignisdelegierte, daher eine Methode wie die folgende:
Kann verwendet werden, um Ihre Veranstaltung zu abonnieren, ohne dass eine explizite Besetzung erforderlich ist
Sie können sogar die Lambda-Syntax verwenden und die Intellisense wird alles für Sie erledigt:
quelle
Ich denke, es gibt kein typedef. Sie können nur einen bestimmten Delegatentyp anstelle des generischen in der GenericClass definieren, d. H.
Dies würde es kürzer machen. Aber was ist mit dem folgenden Vorschlag:
Verwenden Sie Visual Studio. Auf diese Weise, wenn Sie tippten
Es enthält bereits die vollständige Signatur des Ereignishandlers von Intellisense. Drücken Sie die Tabulatortaste und es ist da. Akzeptieren Sie den generierten Handlernamen oder ändern Sie ihn, und drücken Sie erneut die Tabulatortaste, um den Handler-Stub automatisch zu generieren.
quelle
Sowohl in C ++ als auch in C # fehlen einfache Möglichkeiten zum Erstellen eines neuen Typs, der semantisch mit einem vorhandenen Typ identisch ist. Ich finde solche 'typedefs' für die typsichere Programmierung absolut notwendig und es ist eine echte Schande, dass c # sie nicht eingebaut hat. Der Unterschied zwischen
void f(string connectionID, string username)
tovoid f(ConID connectionID, UserName username)
ist offensichtlich ...(Sie können etwas Ähnliches in C ++ mit Boost in BOOST_STRONG_TYPEDEF erreichen.)
Es mag verlockend sein, Vererbung zu verwenden, aber das hat einige wesentliche Einschränkungen:
Die einzige Möglichkeit, in C # etwas Ähnliches zu erreichen, besteht darin, unseren Typ in einer neuen Klasse zusammenzustellen:
Während dies funktioniert, ist es nur für ein typedef sehr ausführlich. Außerdem haben wir ein Problem mit der Serialisierung (dh mit Json), da wir die Klasse über ihre Composed-Eigenschaft serialisieren möchten.
Unten finden Sie eine Hilfsklasse, die das "Curiously Recurring Template Pattern" verwendet, um dies viel einfacher zu machen:
Mit Composer wird die obige Klasse einfach:
Außerdem wird der
SomeTypeTypeDef
Wille auf die gleiche WeiseSomeType
wie bei Json serialisiert .Hoffe das hilft !
quelle
Sie können eine Open-Source-Bibliothek und ein NuGet-Paket namens LikeType verwenden , die ich erstellt habe und die Ihnen das gewünschte
GenericClass<int>
Verhalten verleihen .Der Code würde folgendermaßen aussehen:
quelle
LikeType
Bibliothek.LikeType
Der Hauptzweck des Unternehmens besteht darin, bei der primitiven Besessenheit zu helfen. Daher möchten Sie nicht, dass Sie den umschlossenen Typ so weitergeben können, als wäre es der Wrapper-Typ. Wie in, wenn ichAge : LikeType<int>
dann mache, wenn meine Funktion eine benötigtAge
, möchte ich sicherstellen, dass meine Anrufer eine übergebenAge
, keineint
.Hier ist der Code dafür, viel Spaß! Ich habe aus der dotNetReference-Anweisung die Anweisung "using" in der Namespace-Zeile 106 http://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs übernommen
quelle
Für nicht versiegelte Klassen erben Sie einfach von ihnen:
Für versiegelte Klassen ist es jedoch möglich, typedef-Verhalten mit einer solchen Basisklasse zu simulieren:
quelle
Die beste Alternative zu der
typedef
, die ich in C # gefunden habe, istusing
. Zum Beispiel kann ich die Float-Genauigkeit über Compiler-Flags mit diesem Code steuern:Leider ist es erforderlich, dass Sie dies oben in jeder Datei platzieren, in der Sie es verwenden
real_t
. Derzeit gibt es keine Möglichkeit, einen globalen Namespace-Typ in C # zu deklarieren.quelle