2009-05-14 11 views
6

Uso la riflessione per popolare le proprietà di un oggetto.Impostazione delle proprietà di un oggetto tramite riflessione con diversi tipi di proprietà

Queste proprietà hanno diversi tipi: String, Nullable (double) e Nullable (long) (non so come sfuggire alle parentesi angolari qui ...). I valori per queste proprietà provengono da un dizionario di coppie (stringa, oggetto).

Così, per esempio la mia classe ha le seguenti proprietà:

string Description { get; set; } 
Nullable<long> Id { get; set; } 
Nullable<double> MaxPower { get; set; } 

(in realtà ci sono circa una dozzina di proprietà) e il dizionario avranno voci come < "Descrizione", "Una descrizione">, < "Id", 123456>, < "MaxPower", 20000>

Ora sto usando qualcosa come il seguente per impostare i valori:

foreach (PropertyInfo info in this.GetType().GetProperties()) 
{ 
    if (info.CanRead) 
    { 
     object thisPropertyValue = dictionary[info.Name]; 

     if (thisPropertyValue != null && info.CanWrite) 
     { 
      Type propertyType = info.PropertyType; 

      if (propertyType == typeof(String)) 
      { 
       info.SetValue(this, Convert.ToString(thisPropertyValue), null); 
      } 
      else if (propertyType == typeof(Nullable<double>)) 
      { 
       info.SetValue(this, Convert.ToDouble(thisPropertyValue), null); 
      } 
      else if (propertyType == typeof(Nullable<long>)) 
      { 
       info.SetValue(this, Convert.ToInt64(thisPropertyValue), null); 
      } 
      else 
      { 
       throw new ApplicationException("Unexpected property type"); 
      } 
     } 
    } 
} 

Quindi la domanda è: devo davvero controllare il tipo di ogni proprietà prima di assegnare il valore? C'è qualcosa come un cast che posso eseguire in modo che al valore della proprietà venga assegnato il tipo della proprietà corrispondente?

Idealmente mi piacerebbe essere in grado di fare qualcosa di come seguenti (che ho ingenuamente pensato che potrebbe aver lavorato):

  if (thisPropertyValue != null && info.CanWrite) 
     { 
      Type propertyType = info.PropertyType; 

      if (propertyType == typeof(String)) 
      { 
       info.SetValue(this, (propertyType)thisPropertyValue, null); 
      } 
     } 

Grazie, Stefano

risposta

10

Se i valori sono già di il tipo corretto, quindi no: non devi fare nulla. Se essi potrebbero non essere di destra (int vs float, ecc), il un approccio semplice potrebbe essere:

(modifica aggiustato per i valori nulli)

Type propertyType = info.PropertyType; 
if (thisPropertyValue != null) 
{ 
    Type underlyingType = Nullable.GetUnderlyingType(propertyType); 
    thisPropertyValue = Convert.ChangeType(
     thisPropertyValue, underlyingType ?? propertyType); 
} 
info.SetValue(this, thisPropertyValue, null); 
+0

Stavo per suggerire solo cercando info.SetValue (questo, thisPropertyValue, null); ma questa sembra essere una soluzione migliore. – ChrisF

+0

+1 per il metodo Convert.ChangeType. È un'ottima soluzione per evitare i if in codice. –

+0

@Marc: Grazie, questo ha fatto il trucco;) @ ChrisF: info.SetValue (this, thisPropertyValue, null) ha generato un'eccezione durante il tentativo di convertire da int a double in uno dei miei casi di test. –

Problemi correlati