Le classi di costanti che dovrebbero implementare un'interfaccia

3

Ho bisogno di creare una classe / classi in C # che contengano costanti per le proprietà dei formati carta come dimensioni, proporzioni, risoluzione orizzontale e verticale ecc. per vari formati di carta come A4, Letter e così via. La prima idea era di creare un'interfaccia (o classe astratta) IPaperSize da cui avremmo ereditato classi A4Paper, LetterPaper ecc. Con i valori memorizzati all'interno. Ha anche senso rendere statiche le classi poiché memorizza solo le costanti, ma con il progetto corrente non riesco a renderlo statico a causa dell'ereditarietà dall'interfaccia. Qual è l'approccio migliore qui?

    
posta Nemanja Petrović 04.05.2018 - 09:23
fonte

2 risposte

10

I need to create a class/classes in C#...

No, è necessario creare un set di valori fissi. Quindi non pensare immediatamente alle classi. Lascia questa decisione fino a tardi.

Quindi, è necessario un insieme di valori, raggruppati per tipo di carta. La struttura che viene in mente quindi è un dizionario. La dimensione della carta è la chiave, gli aspetti di quella dimensione sono il valore.

Ora, a questo punto, dobbiamo prendere una decisione. Parli di molte proprietà di ogni formato di carta. Ma in realtà, sono necessari solo due: la larghezza e l'altezza. Da questo, è possibile calcolare tutte le proporzioni ecc. Quindi li calcoli manualmente una volta e definisci più proprietà, o semplicemente imposta la larghezza e l'altezza e calcoli gli altri valori in fase di runtime? Andiamo a calcolarli una sola volta in fase di esecuzione, all'avvio.

Quindi, con questo, ora sappiamo che abbiamo bisogno di una classe (o di una struct, se preferisci, visto che stiamo usando C # qui, ma resterò con una classe):

public sealed class PaperDetails
{
    public PaperDetails(double width, double height)
    {
        Width = width;
        Height = height;
        AspectRatio = width/height;
        ...
    }

    public double Width {get;}
    public double Height {get;}
    public double AspectRatio {get;}
    ...
}

Quindi, dobbiamo identificare i tipi di carta. Un enum sembra la scelta ideale qui:

public enum PaperSizes
{
    A4,
    Letter,
    ...
}

Quindi possiamo creare il nostro dizionario:

private static readonly Dictionary<PaperSizes, PaperDetails> _paperTypes = 
    new Dictionary<PaperSizes, PaperDetails>
    {
        [PaperSizes.A4] = new  PaperDetails(297, 420),
        [PaperSizes.Letter] = new PaperDetails(270, 200),
        ...
    };

Infine, abbiamo solo bisogno di una classe statica per incapsulare quel dizionario e per fornire accesso in sola lettura ad esso:

public static class PaperDetailsPerSize
{
    private static readonly Dictionary<PaperSizes, PaperDetails> _paperTypes = 
        new Dictionary<PaperSizes, PaperDetails>
        {
            [PaperSizes.A4] = new  PaperDetails(297, 420),
            [PaperSizes.Letter] = new PaperDetails(270, 200),
            ...
        };

    public static PaperDetails GetPaperDetails(PaperSizes size) => _paperTypes[size];
}

Lavoro svolto e non è necessario preoccuparsi delle classi statiche che non sono in grado di implementare interfacce. Non abbiamo usato le costanti (tranne i valori di larghezza e altezza, che sono valori, non nominati, costanti). Se questo è un problema, quindi crea un gruppo di costanti con nome per definire quei valori e popolare il dizionario con loro.

    
risposta data 04.05.2018 - 10:55
fonte
1

Piuttosto che andare con costanti, è possibile creare una classe non-static immutable (con proprietà get-only) e fornire una serie di istanze predefinite. In realtà non deve ereditare nulla, né implementare alcuna interfaccia, soprattutto se memorizza solo questi valori e non ha alcun comportamento. Se la classe è fata piccola, considera di renderla una struct (vedi questo ) e fornendo un'implementazione personalizzata per GetHashCode ed Equals. Per quanto riguarda come fornire questi valori predefiniti, è possibile creare un'altra classe con una serie di metodi di produzione statici (o proprietà - A4, Lettera, ecc.) Che restituiscono l'istanza appropriata (creandola al volo; in alternativa, è possibile creare un'istanza di tutti in anticipo e restituisce solo istanze esistenti).

    
risposta data 04.05.2018 - 09:55
fonte

Leggi altre domande sui tag