398 Stimmen

Äquivalent von typedef in C#

Gibt es ein typedef Äquivalent in C#, oder eine Möglichkeit, eine Art von ähnlichen Verhalten zu erhalten? Ich habe etwas gegoogelt, aber überall, wo ich suche, scheint negativ zu sein. Derzeit habe ich eine Situation ähnlich der folgenden:

class GenericClass<T> 
{
    public event EventHandler<EventData> MyEvent;
    public class EventData : EventArgs { /* snip */ }
    // ... snip
}

Nun muss man kein Raketenwissenschaftler sein, um herauszufinden, dass dies sehr schnell zu einer Menge Tipparbeit führen kann (Entschuldigung für das schreckliche Wortspiel), wenn man versucht, einen Handler für dieses Ereignis zu implementieren. Es würde am Ende etwas wie dieses sein:

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();
}

Aber 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: d.h. vielleicht typedefing die EventHandler anstelle der Notwendigkeit, es neu zu definieren, um ähnliches Verhalten zu erhalten.

413voto

Jon Skeet Punkte 1325502

Nein, es gibt keine echte Entsprechung von typedef. Sie können 'using'-Direktiven innerhalb einer Datei verwenden, z.B.

using CustomerList = System.Collections.Generic.List<Customer>;

aber das wirkt sich nur auf diese Quelldatei aus. In C und C++ ist meine Erfahrung, dass typedef wird in der Regel innerhalb von .h-Dateien verwendet, die weitläufig eingebunden sind - so kann eine einzelne typedef kann für ein ganzes Projekt verwendet werden. Diese Möglichkeit gibt es in C# nicht, da es keine #include Funktionalität in C#, die es Ihnen ermöglichen würde, die using Direktiven aus einer Datei in eine andere zu übertragen.

Zum Glück ist das von Ihnen genannte Beispiel する haben einen Fix - implizite Methodengruppen-Konvertierung. Sie können Ihre Ereignis-Abonnement-Zeile zu einfach ändern:

gcInt.MyEvent += gcInt_MyEvent;

:)

46voto

Jon hat wirklich eine gute Lösung gefunden, ich wusste nicht, dass man das machen kann!

Manchmal habe ich von der Klasse geerbt und ihre Konstruktoren erstellt. Z.B..

public class FooList : List<Foo> { ... }

Das ist zwar nicht die beste Lösung (es sei denn, Ihre Baugruppe wird von anderen Personen verwendet), aber es funktioniert.

23voto

palswim Punkte 11356

Wenn Sie wissen, was Sie tun, können Sie eine Klasse mit impliziten Operatoren definieren, um zwischen der Alias-Klasse und der eigentlichen Klasse zu konvertieren.

class TypedefString // Example with a string "typedef"
{
    private string Value = "";
    public static implicit operator string(TypedefString ts)
    {
        return ((ts == null) ? null : ts.Value);
    }
    public static implicit operator TypedefString(string val)
    {
        return new TypedefString { Value = val };
    }
}

Ich befürworte das zwar nicht und habe so etwas auch noch nie benutzt, aber unter bestimmten Umständen könnte es vielleicht funktionieren.

15voto

JJJ Punkte 439

Mit C# 10 können Sie jetzt Folgendes tun

global using Bar = Foo

Das funktioniert wie ein Typedef innerhalb des Projekts.

Ich habe es noch nicht eingehend getestet, es könnte also noch Macken geben.

Ich benutze es wie

global using DateTime = DontUseDateTime

Wobei DontUseDateTime eine Struktur ist, die als Obsolete markiert ist, um die Leute zu zwingen, NodaTime zu verwenden.

6voto

OregonGhost Punkte 22841

Ich glaube, es gibt keinen Typedef. Sie könnten nur einen spezifischen Delegatentyp anstelle des generischen in der GenericClass definieren, d.h.

public delegate GenericHandler EventHandler<EventData>

Das würde ihn kürzer machen. Aber wie wäre es mit dem folgenden Vorschlag?

Verwenden Sie Visual Studio. Auf diese Weise können Sie bei der Eingabe von

gcInt.MyEvent += 

bietet es bereits die vollständige Ereignisbehandlungssignatur von Intellisense. Drücken Sie TAB und es ist da. Akzeptieren Sie den generierten Handler-Namen oder ändern Sie ihn, und drücken Sie dann erneut TAB, um den Handler-Stub automatisch zu generieren.

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