2015-04-27 13 views
8

In Haskell, esistono due modi per fornire un alias per i tipi: type e newtype. type fornisce un tipo sinonimi, che significa che il tradurre viene considerata dal tipo correttore come esattamente lo stesso del tipo di originale:Qual è l'equivalente di C# al nuovo tipo di Haskell?

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

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

Un newtype è simile, ma è considerato per il tipo di controllo come un tipo diverso :

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#, è possibile definire il tipo di sinonimi con un alto livello using dichiarazione:

using UserId = Int; 

Tuttavia, un alias di tipo fortemente controllato e controllato dal compilatore non sembra essere presente in C# per impostazione predefinita. Ho esaminato la generazione automatica del codice con i modelli T4 e CodeDOM per generare un wrapper di classe, ma non so davvero come potrei integrarli in modo pulito nel mio flusso di programmazione.

Idealmente, vorrei poter dire su un livello superiore:

// Something like this? 
using Int.UserId; 

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

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

Questa calci generazione del codice in marcia al momento della compilazione. Se ciò non è possibile o fornisce un problema di pollo e uova per IntelliSense, un'opzione di compilazione automatica che viene eseguita ogni x minuti (o un pulsante o qualsiasi altra cosa) sarebbe piacevole.

+2

Puoi fornire qualche informazione sul perché vuoi farlo? –

+0

Perché vuoi compilare il tuo codice ogni x minuti? – Georg

+1

A cosa serve nascondere un tipo sotto un altro nome di tipo? – Franck

risposta

13

No, C# non ha questa caratteristica. Il più vicino a cui puoi arrivare sono le strutture.

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

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

In questo modo, il compilatore tratta i effettivamente UserId e int tipi come differenti. Inoltre, è possibile aggiungere altri metodi a UserId che è logico dato che il tuo int è effettivamente un ID utente. Si noti inoltre che questo non ha alcun effetto sul runtime, l'utilizzo di una struct con un singolo campo int non causa alcun sovraccarico sull'utilizzo di int direttamente.

Edit: Perché hai chiesto di T4, se si lavora con Visual Studio, è possibile creare facilmente un nuovo modello T4 testo che si espanderà a (C#) - codice e verrà compilato automaticamente. Il modello verrà eseguito ogni volta che lo salvi.

+1

Una cosa importante dei newtype in Haskell è che sono un'astrazione molto economica (infatti sono ottimizzati completamente dopo il controllo dei tipi). Anche in questo senso, le strutture sono la risposta corretta. – kqr

Problemi correlati