Aggiunge / modifica dinamicamente gli attributi dei valori in C #

1

Voglio taggare i valori delle variabili con un attributo "qualità" che può essere modificato dinamicamente durante l'esecuzione dei miei programmi. Il mio primo pensiero è stato quello di abusare della funzionalità degli attributi standard taggando il valore con il mio attributo di qualità personalizzato. EG

[QualityAttribute(Quality.Bad)]
int value = 0;
...
value = 1;
(** somehow set QualityAttribute of value to Quality.Good **)

Ma da quello che ho visto gli attributi erano intesi come una misura statica e sono inseriti in meta-dati, rendendo apparentemente impossibile ciò che voglio fare.

Un'alternativa sarebbe quella di creare una struct / class che contenga sia la variabile che la qualità. EG

class Value
{
  public Quality quality = Quality.Bad;
  public int value = 0;
}
...
Value value = new Value();
value.value = 1;
value.quality = Quality.Good;

Funzionerà (ed è simile a ciò che viene usato per supportare i tipi nullable), ma non mi piace il livello aggiuntivo di riferimento indiretto per ottenere il valore.

Esiste un altro modo che consente l'accesso diretto al valore e supporta facilmente il valore di tagging con un attributo personalizzato e dinamicamente modificabile?

    
posta Peter M 06.07.2017 - 14:22
fonte

3 risposte

0

Questa è fondamentalmente un'espansione rispetto alla risposta di @ CandiedOrange, fai un pop up su di loro se finisci per piacergli.

Perché non implementare qualcosa di simile a un valore nullo?

Immette la classe "Qualitable":

public class Qualitable<T>
{
    T Value { get; set; }
    QualityEnum Quality;  

    public Qualitable(T Value, QualityEnum Quality)
    {
        this.Value = Value;
        this.Quality = Quality;
    }
}

Quindi, puoi farlo sul tuo codice:

Qualitable<int> myThing = new Qualitable<int>(10, QualityEnum.VeryGood)

if(myThing.Quality == QualityEnum.VeryGood)
{
    DoSomething(myThing.Value);
    //Pop an upvote 
}
else
{ 
    DoSomethingElse(myThing.Value);
   //Do it anyway, me tries hard :(
}
    
risposta data 06.07.2017 - 22:56
fonte
2

Mi piace l'alternativa struct / class che contiene sia la variabile che la qualità. Non mi piace usare le cose statiche senza un buon motivo. Tranne che non mi piace anche schiacciare due astrazioni diverse. Le informazioni meta semplicemente non sono allo stesso livello di quelle che descrive.

Questo sta gridando "usa uno stile monadico " per me.

Puoi annidarli e mettere valore a un livello e qualità a un altro. O mantenere la qualità come proprietà su quello che è fondamentalmente un contenitore generico.

Questo significa che il tuo valore può essere qualsiasi cosa e non è legato alla tua interfaccia di qualità. Puoi scambiare i tipi secondo necessità.

Potresti essere sul punto di lamentarti del fatto che questo non è diretto, ma cerca il modo giusto per accedere a una monade e chiediti se questo non è migliore.

Questa risposta sta suscitando alcune polemiche, quindi permettimi di spiegarlo un po 'di più senza affogarlo nei dettagli.

La cosa principale che sto cercando in questo design è di non forzare la ramificazione.

Se questa è solo una struttura o una pila di getter, gli utenti sono costretti a testare la qualità e prendere una decisione basata su di essa. Sarebbe bello se la logica venisse abbattuta e sottratta, in modo che il bene o il male tu ottenga il valore che ti serve quando lo chiedi.

Se questo significa aggiungere metodi come UnlessBad(T other) o qualcos'altro, non ne sono del tutto sicuro. Ho pensato che valesse la pena.

public Quality<Integer> qualityAdd(Quality<Integer> val1, Quality<Integer> val2) {
    return
        val1.flatMap( first =>
        val2.flatMap( second =>
        Quality.of(first + second)
    ));
}

Questo aggiungerà gli int insieme per fare una nuova buona qualità purché entrambi siano di buona qualità. Altrimenti viene restituita una cattiva qualità. Questa è una catena corta ma non esiste un limite prestabilito.

Fatto in questo modo tutti i controlli per la qualità sono nascosti. Quando viene rilevata una cattiva qualità, la catena può essere arrestata semplicemente non chiamando più lambda e restituendo una cattiva qualità. In alternativa, tutti gli int possono essere sommati e la qualità può essere OR sulla via del ritorno. Ad ogni modo, uno cattivo girerebbe tutto male.

    
risposta data 06.07.2017 - 14:39
fonte
0

Gli attributi sono statici e non possono essere modificati in fase di esecuzione, quindi è un po 'come un vicolo cieco. Potresti voler dare un'occhiata al Type Descriptor, potrebbe risolvere il tuo problema ...

link

link

    
risposta data 06.07.2017 - 17:21
fonte

Leggi altre domande sui tag