Posso memorizzare una manciata di oggetti costanti e complessi in una struttura simile ad enum in C #?

6

Sto creando un'applicazione ASP.NET MVC per lavorare con i dati di un'API che ha un paio di endpoint diversi per regioni geografiche diverse. Ogni regione ha un nome, un ID alfanumerico e un URL host. ad esempio Western Europe - WE1 - we.api.com .

Ci sono meno di una dozzina di regioni e i loro valori non cambieranno, anche se le regioni potrebbero essere aggiunte o rimosse in futuro. Vorrei memorizzarli in modo sostenibile in modo da poterli passare facilmente come parametri per le funzioni. ad esempio GetUserData("username", Region.WesternEurope, true) .

Ho usato ENums per questo prima per le API in cui gli endpoint erano definiti da un singolo valore ma non riesco a decidere come procedere. Un'opzione che ho preso in considerazione è la creazione di un Enum con solo i nomi e quindi la mappatura degli oggetti in un dizionario in una classe statica, ma non sono un programmatore molto esperto e non so se sarebbe una buona idea .

    
posta Lawyerson 19.12.2016 - 01:13
fonte

2 risposte

12

Potresti fare così:

class Region
{
    public string name { get; private set; }
    public string id { get; private set; }
    public string url { get; private set; }

    // private constructor
    Region() {}

    // static members
    public static Region WesternEurope = new Region() {
        name = "Western Europe",
        id = "WE1",
        url = "we.api.com"
    };
}

Penso che il costruttore privato implichi che le istanze possono essere create solo all'interno della classe, ad es. come membri statici, così puoi controllare quali istanze vengono create.

Alla fine è possibile caricare le istanze da un'origine esterna (file di dati, database o registro).

Il commento di Per Doc Brown, di seguito, è possibile implementare questo caricamento in un costruttore statico della classe Region (ad esempio per caricare tutte le regioni), o implementare tale caricamento in un accesso get statico come mostrato di seguito (ad esempio per caricare ogni regione solo nel tempo, se e quando è acceduto).

In un commento qui sotto, Rumen Georgiev ha suggerito la seguente alternativa (che è, IMO, più complicata, e non necessaria, e non thread-safe):

// static members
private static Region _westernEurope;
public static Region WesternEurope 
{
    get 
    {
        if (_westernEurope == null)
        {
            _westernEurope = new Region() 
            {
                name = "Western Europe",
                id = "WE1",
                url = "we.api.com"
            };
        }
        return _westernEurope;
    }
}

Una versione alternativa, che è sia thread-safe che consente ancora l'inizializzazione pigra di WesternEurope , utilizza il tipo Lazy<> :

    private static Lazy<Region> _westernEurope = new Lazy<Region>(
        () => new Region() 
        {
            name = "Western Europe",
            id = "WE1",
            url = "we.api.com"
        });

    public static Region WesternEurope => _westernEurope.Value;

È discutibile se valga la pena farlo in questo caso, anche se il sovraccarico di creazione delle istanze quando Region è inizializzato staticamente è probabile che sia piccolo.

    
risposta data 19.12.2016 - 02:34
fonte
0

La risposta dipende tutto dalle tue esigenze nel tempo.

Se il tuo unico requisito è un codice pulito che sia facile da capire, ti suggerirei una classe diretta come questa:

internal static class regionStrings {

  static public string Ireland { get; private set; }

  static regionStrings()
  {
    Ireland = "eu-west-1";
  }
}
    
risposta data 19.12.2016 - 02:34
fonte

Leggi altre domande sui tag