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.

6voto

Keith Punkte 141163

C# unterstützt einige vererbte Kovarianz für Ereignisdelegierte, so dass eine Methode wie diese:

void LowestCommonHander( object sender, EventArgs e ) { ... } 

Kann verwendet werden, um Ihr Ereignis zu abonnieren, kein expliziter Cast erforderlich

gcInt.MyEvent += LowestCommonHander;

Sie können sogar Lambda-Syntax verwenden und die Intellisense wird alles für Sie erledigen:

gcInt.MyEvent += (sender, e) =>
{
    e. //you'll get correct intellisense here
};

5voto

Matt Klein Punkte 7076

Sie können eine Open-Source-Bibliothek und ein NuGet-Paket namens LikeType die ich erstellt habe und die Ihnen die GenericClass<int> Verhalten, nach dem Sie suchen.

Der Code würde wie folgt aussehen:

public class SomeInt : LikeType<int>
{
    public SomeInt(int value) : base(value) { }
}

[TestClass]
public class HashSetExample
{
    [TestMethod]
    public void Contains_WhenInstanceAdded_ReturnsTrueWhenTestedWithDifferentInstanceHavingSameValue()
    {
        var myInt = new SomeInt(42);
        var myIntCopy = new SomeInt(42);
        var otherInt = new SomeInt(4111);

        Assert.IsTrue(myInt == myIntCopy);
        Assert.IsFalse(myInt.Equals(otherInt));

        var mySet = new HashSet<SomeInt>();
        mySet.Add(myInt);

        Assert.IsTrue(mySet.Contains(myIntCopy));
    }
}

5voto

shakram02 Punkte 8742

Hier ist der Code dafür, viel Spaß, ich habe ihn aus der dotNetReference übernommen Geben Sie die "using"-Anweisung innerhalb der Namespace-Zeile 106 http://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs

using System;
using System.Collections.Generic;
namespace UsingStatement
{
    using Typedeffed = System.Int32;
    using TypeDeffed2 = List<string>;
    class Program
    {
        static void Main(string[] args)
        {
        Typedeffed numericVal = 5;
        Console.WriteLine(numericVal++);

        TypeDeffed2 things = new TypeDeffed2 { "whatever"};
        }
    }
}

5voto

OS Freak Punkte 1

Ich würde es tun

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

3voto

Vlad Rudenko Punkte 1863

Bei nicht versiegelten Klassen erben Sie einfach von ihnen:

public class Vector : List<int> { }

Aber für versiegelte Klassen ist es möglich, typedef Verhalten mit solchen Basisklasse zu simulieren:

public abstract class Typedef<T, TDerived> where TDerived : Typedef<T, TDerived>, new()
{
    private T _value;

    public static implicit operator T(Typedef<T, TDerived> t)
    {
        return t == null ? default : t._value;
    }

    public static implicit operator Typedef<T, TDerived>(T t)
    {
        return t == null ? default : new TDerived { _value = t };
    }
}

// Usage examples

class CountryCode : Typedef<string, CountryCode> { }
class CurrencyCode : Typedef<string, CurrencyCode> { }
class Quantity : Typedef<int, Quantity> { }

void Main()
{
    var canadaCode = (CountryCode)"CA";
    var canadaCurrency = (CurrencyCode)"CAD";
    CountryCode cc = canadaCurrency;        // Compilation error
    Concole.WriteLine(canadaCode == "CA");  // true
    Concole.WriteLine(canadaCurrency);      // CAD

    var qty = (Quantity)123;
    Concole.WriteLine(qty);                 // 123
}

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