2015-04-27 13 views
8

In Haskell gibt es zwei Möglichkeiten, einen Alias ​​für Typen bereitzustellen: type und newtype. type ein Typ Synonym, die das Synonym bedeutet, wird durch die Art checker gilt als genau die gleiche wie die ursprüngliche Typ:Was ist C# entspricht Haskells Newtype?

type UserId = Int 
hasAccess :: UserId -> Bool 
hasAccess id = {-- stuff --} 

-- Elsewhere in the program 
login :: Int -> Bool 
login n = hasAccess n -- Typechecker won't complain 

A newtype ist ähnlich, wird aber von der Art checker als eine andere Art betrachtet :

using UserId = Int; 
0123:

newtype UserId = UserId Int 
hasAccess :: UserId -> Bool 
hasAccess (UserId id) = {-- stuff --} 

-- Elsewhere in the program 
login :: Int -> Bool 
login n = hasAccess n -- Typechecker will complain, n isn't a UserId ! 

In C# können Sie Typ Synonyme mit einem Top-Level-using Deklaration definieren

Ein stark typisierter, vom Compiler überprüfter Typalias scheint jedoch in C# standardmäßig nicht vorhanden zu sein. Ich habe die automatische Codegenerierung mit T4-Templates und CodeDOM untersucht, um einen Klassenwrapper zu generieren, aber ich weiß nicht wirklich, wie ich diese sauber in meinen Programmierfluss integrieren könnte.

Idealerweise würde ich in der Lage sein mag auf einem Top-Level zu sagen:

// Something like this? 
using Int.UserId; 

/* Elsewhere */ 
var id = new UserId(5); 

public bool HasAccess(UserId id) 
{ 
    /* Stuff */ 
} 

Dieser schlägt die Code-Generierung in Gang zur Compile-Zeit. Wenn dies nicht möglich ist oder ein Problem mit Huhn und Ei für IntelliSense besteht, wäre eine automatische Kompilierungsoption, die alle x Minuten (oder eine Schaltfläche oder was auch immer) läuft, nett.

+2

Können Sie Hintergrundinformationen dazu liefern, warum Sie dies tun möchten? –

+0

Warum möchten Sie Ihren Code alle x Minuten kompilieren? – Georg

+1

Was benutzt man, um einen Typ unter einem anderen Typnamen zu verstecken? – Franck

Antwort

13

Nein, C# hat keine solche Funktion. Das nächste, was Sie dazu finden können, sind Strukturen.

public struct UserId 
{ 
    public int Id { get; private set; } 

    public UserId(int id) : this() { Id = id; } 
} 

Auf diese Weise behandelt der Compiler in der Tat UserId und int als verschiedene Typen. Darüber hinaus können Sie UserId weitere Methoden hinzufügen, die sinnvoll sind, da Ihre int tatsächlich eine Benutzer-ID ist. Beachten Sie außerdem, dass dies keine Auswirkungen auf die Laufzeit hat. Die Verwendung einer Struktur mit einem einzelnen Feld int verursacht keinen Overhead, wenn Sie direkt int verwenden.

Bearbeiten: Da Sie nach T4 gefragt haben, wenn Sie mit Visual Studio arbeiten, können Sie einfach eine neue T4 Textvorlage erstellen, die auf (C#) - Code erweitert wird und automatisch kompiliert wird. Die Vorlage wird jedes Mal ausgeführt, wenn Sie sie speichern.

+1

Eine wichtige Sache über neue Typen in Haskell ist, dass sie eine sehr billige Abstraktion sind (tatsächlich werden sie nach der Typprüfung vollständig wegoptimiert). Auch in diesem Sinne sind Strukturen die richtige Antwort. – kqr