2015-05-20 25 views
7

Considerate questo codice:Garantire inizializzazione delle variabili C#

public string Variable1 { get; set;} 
public int Variable2 { get; set;} 

public void Function() 
{ 
// Has been Variable1 Initialized? 
} 

All'interno della funzione, voglio sapere se un valore è stato inviato al Variabile1 & Variabile2, prima della chiamata di funzione,

anche se i valori di default sono stati inviati, che è ok (null per stringa & 0 per int)

+4

Penso che la meta-risposta sia "quindi non farlo". Assicurarsi che tutte le variabili siano inizializzate nel costruttore. – Martijn

+0

Cosa succede se ho due funzioni. F1 e F2, ognuno utilizza entrambe le variabili. Ma per F1 devo essere sicuro che il chiamante della funzione abbia impostato valori per le variabili, anche se sono nulle.Per la F2 non mi interessa, non voglio costringerlo a mandare qualcosa nel costruttore! –

+0

se per F1 hai bisogno del * chiamante * per impostare le variabili, perché non le passi come argomenti in F1? – Martijn

risposta

8

considerare l'utilizzo di un semplice involucro come questo:

public struct AssignableProperty<T> 
{ 
    private T _value; 

    public T Value 
    { 
     get { return _value; } 
     set 
     { 
      WasAssigned = true; 
      _value = value; 
     } 
    } 

    public bool WasAssigned { get; private set; } 

    public static implicit operator AssignableProperty<T>(T data) 
    { 
     return new AssignableProperty<T>() { Value = data }; 
    } 

    public static bool operator ==(AssignableProperty<T> initial, T data) 
    { 
     return initial.Value.Equals(data); 
    } 

    public static bool operator !=(AssignableProperty<T> initial, T data) 
    { 
     return !initial.Value.Equals(data); 
    } 

    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

Allora il vostro sguardo class'll in questo modo:

public class Test 
{ 
    public AssignableProperty<string> Variable1 { get; set; } 
    public AssignableProperty<int> Variable2 { get; set; } 

    public void Function() 
    { 
     if(Variable1.WasAssigned&&Variable2.WasAssigned) 
      //do stuff 
    } 
} 

Si può andare oltre e aggiungere eccezioni tiro o un contratto di getter, quindi se qualcuno proverà ad accedere al valore non inizializzato, genererà un'eccezione o mostrerà un avviso

+0

Lo svantaggio di questo approccio è che ora devi dire 'instance.Variable1.Value =" something "' per impostare la proprietà. – Sean

+0

@Sean Hai ragione, ti salva la verbosità e la ripetizione ovunque desideri una bandiera. –

+1

@Sean nope, AFAIK è possibile ignorare gli operatori di cast e di confronto in modo da poter eseguire un semplice assegnamento come Variable1 = "qualcosa" e il confronto con il tipo iniziale (T) non sarà un problema. Quello che ti manca veramente è la memoria –

2

Alcune basi di valore di default in C#:

Quando viene creata un'istanza di una classe (o una struct), tutti i campi vengono inizializzati al rispettivo valore predefinito.

Per i tipi di riferimento, sarà null. Per i tipi di valore, sarà equivalente a 0. Questo è facilmente spiegabile in quanto la gestione della memoria assicura che la nuova memoria allocata sia inizializzata a 0x0 byte.

Le proprietà automatiche nascondono il campo generato, ma ce n'è uno. Quindi valgono le stesse regole.

Ora per rispondere alla tua domanda, il modo migliore per assicurarsi che i valori sono inizializzati è quello di fare un costruttore con un parametro per ogni campo/proprietà e per nascondere il costruttore di default senza parametri:

public Yourtype(String param1, Int32 param2) 
{ 
    this.Variable1 = param1; 
    this.Variable2 = param2; 
} 

private Yourtype() { } 

Altre alternative sono descritte nelle risposte @Sean e @Alex se solo un sottoinsieme di proprietà/campi deve essere inizializzato/controllato. Ma questo nasconde un overhead (uno bool per ogni proprietà/campo e qualche riferimento indiretto).

-2

Bene, si può semplicemente fare un controllo su entrambe le variabili per vedere se hanno un valore assegnato a li nella funzione

public void Function() 
{ 

    if (String.IsNullOrEmpty(Variable1) && Variable2 ==0) 
    { 
     // Variables are not assigned 
    } 

} 
+1

E se 'Variable1' è' null', vuol dire che qualcuno ha inizializzato il valore o no? –

+0

Se si desidera verificare un valore predefinito di un tipo in fase di esecuzione, è necessario utilizzare: http://stackoverflow.com/questions/1281161/how-to-get-the-default-value-of-a-type-if -the-type-is-only-known-as-system-type –

+0

Non desidero controllare un valore predefinito. Voglio verificare se prima della chiamata alla funzione qualcuno ha inviato qualcosa al var, anche se questo è NULL o zero o qualsiasi valore predefinito per ogni tipo. –

0

Per i tipi di riferimento che sarà necessario aggiungere una bandiera:

string m_Variable1; 
bool m_IsVariable1Set; 

public string Variable1 
{ 
    get{return m_Variable1;} 
    set{m_IsVariable1Set = true; m_Variable1 = value;} 
} 

Per i tipi di valore è possibile utilizzare un valore nullable

int? m_Variable2; 

int Variable2 
{ 
    get{return m_Variable2.GetValueOrDefault();} 
    set{m_Variable2 = value;} 
} 

Che si può quindi verificare se è stato impostato utilizzando m_Variable2.HasValue.

Problemi correlati