2009-08-18 24 views
15

Ho classe (Cliente) che contiene più di 200 variabili stringa come proprietà. Sto usando il metodo con parametro di chiave e valore. Sto cercando di fornire la chiave e il valore dal file xml. Per questo, il valore deve essere sostituito dalla proprietà della classe Customer (variabili stringa).stringa a nome variabile

cioè

Customer 
{ 
    public string Name{return _name}; 

    public string Address{return _address}; 
} 


CallInput 
{ 
    StringTempelate tempelate = new StringTempelate(); 
    foreach(item in items) 
    tempelate .SetAttribure(item.key, item.Value --> //Say this value is Name, so it has to substitute Customer.Name 
} 

è possibile?

+6

Forse dovresti prendere in considerazione la riprogettazione della tua classe, 200 proprietà è piuttosto pazzesca: p Ma per te la riflessione sul metodo è la strada da percorrere. Puoi usare un dizionario come esempio. –

+0

Cercate John

internet via

+0

@ John Nolan, proprio simile a quello – Mohanavel

risposta

20

È possibile utilizzare la riflessione per impostare le proprietà 'in base al nome'.

using System.Reflection; 
... 
myCustomer.GetType().GetProperty(item.Key).SetValue(myCustomer, item.Value, null); 

si può anche leggere le proprietà con GetValue, o ottenere un elenco di tutti i nomi di proprietà che utilizzano GetType(). GetProperties(), che restituisce un array di PropertyInfo (la proprietà Name contiene il nome proprietà)

13

Bene, è possibile utilizzare Type.GetProperty(name) per ottenere un PropertyInfo, quindi chiamare GetValue.

Ad esempio:

// There may already be a field for this somewhere in the framework... 
private static readonly object[] EmptyArray = new object[0]; 

... 

PropertyInfo prop = typeof(Customer).GetProperty(item.key); 
if (prop == null) 
{ 
    // Eek! Throw an exception or whatever... 
    // You might also want to check the property type 
    // and that it's readable 
} 
string value = (string) prop.GetValue(customer, EmptyArray); 
template.SetTemplateAttribute(item.key, value); 

Si noti che se si esegue questa operazione molto si può decidere di convertire le proprietà in Func<Customer, string> istanze delegato - che sarà molto più più veloce, ma più complicato. Vedere il mio post sul blog su creating delegates via reflection per ulteriori informazioni.

4

Utilizzare la riflessione e un oggetto dizionario come raccolta di elementi.

Dictionary<string,string> customerProps = new Dictionary<string,string>(); 
Customer myCustomer = new Customer(); //Or however you're getting a customer object 

foreach (PropertyInfo p in typeof(Customer).GetProperties()) 
{ 
    customerProps.Add(p.Name, p.GetValue(customer, null)); 
} 
5

La riflessione è un'opzione, ma 200 proprietà sono ... molto. Come succede, sto lavorando a qualcosa del genere al momento, ma le classi sono create da code-gen. Per adattare "per nome" utilizzo, ho aggiunto un indicizzatore (durante la fase di generazione del codice):

public object this[string propertyName] { 
    get { 
     switch(propertyName) { 
      /* these are dynamic based on the the feed */ 
      case "Name": return Name; 
      case "DateOfBirth": return DateOfBirth; 
      ... etc ... 
      /* fixed default */ 
      default: throw new ArgumentException("propertyName"); 
     } 
    } 
} 

Questo dà la comodità del "per nome", ma buone prestazioni.

Problemi correlati