2013-10-21 11 views
11

Diciamo che ho un oggetto che rappresenta un campo di dati, quell'oggetto ha bisogno delle seguenti proprietà: Nome, Tipo, Valore, Lunghezza. Qui è l'oggetto:Elenco generico di oggetti generici

class Field<T> 
{ 
    public string Name { get; set; } 
    public Type Type 
    { 
     get 
     { 
      return typeof(T); 
     } 
    } 
    public int Length { get; set; } 
    public T Value { get; set; } 
} 

ho usato farmaci generici, perché voglio forzare l'utente del codice di essere solo in grado di assegnare un valore di certo tipo.
Ora il problema è quando voglio creare un elenco di campi.
Se creo l'elenco come List<Field<object>>, allora possiamo assegnare qualsiasi valore a un determinato campo nell'elenco e quando chiediamo il tipo, otteniamo "oggetto".
Il fatto è che in questa lista potrei desiderare che pochi campi contengano stringhe, pochi dati, date e persino oggetti personalizzati che a loro volta avranno un elenco di campi ...
I generici sono una buona soluzione per qualcosa di simile quella? Se sì, come andrei a implementarlo? In caso contrario, qual è il modo migliore?

--- EDIT ---
solo per aggiungere un po 'più di fondo:
1. Mi potrebbe desiderare un elenco di campi, e ogni campo terrà diverso tipo di dati, in questo modo:

List<Field<object>> lst = new List<Field<object>>(); 
lst.Add(new Field<string>()); 
lst.Add(new Field<int>()); 
lst.Add(new Field<SomeObjectFromMyApp>()); 

2. in seguito dovrò interrogare questi oggetti, ed i loro attributi automaticamente in un ciclo, qualcosa del genere:

foreach(Field<object> fld in lst) 
{ 
    Type t = fld.Type; 
    //do some other stuff 
} 
+0

Cosa vuoi esattamente? Non capisco questa frase: "in quella lista potrei volere pochi campi che contengono stringhe, pochi detengono valori, date e persino oggetti personalizzati che a loro volta avranno una lista di campi" – Florian

+0

Esattamente quello che dice, avrò pochi diversi elenchi di campi, ma ogni campo su quell'elenco potrebbe contenere tipi di dati diversi (int, string o qualche oggetto personalizzato). –

risposta

9

Sì, farmaci generici è una buona scelta. La chiave per raggiungere tipo di sicurezza (e di essere identificare il tipo con la proprietà Type è quello di aggiungere un astrazione tra la lista e Field<T> classe.

Avere Field<T> implementare l'interfaccia IField. Questa interfaccia non ha bisogno di alcun membro.

quindi dichiarare la vostra lista come List<IField>.

in questo modo si vincola l'elenco per contenere solo i campi, ma ogni campo può essere di tipo diverso.

per poi leggere i valori più tardi, basta fare

foreach(var field in list) 
{ 
    var type = field.Type; 
    .... 
} 
+0

Questo risolverebbe un problema con la creazione dell'elenco, ma non risolverebbe il problema della lettura dei valori, poiché ora dovrei eseguire il cast in un campo appropriato <_type_>, e non c'è modo che conosca il \ _type \ _ a quella volta ... –

+0

@DanielGruszczyk Perché dovresti lanciare?Ognuno di questi funzionerà correttamente: var field = list [index] o IField field = list [index] –

+0

Verificherò, in quanto l'interfaccia sarebbe effettivamente più adatta a me dal momento che posso applicare determinati metodi sulla classe :) –

10

suggerisco di definire un'interfaccia e campo implementa tale interfaccia

public interface IField 
    { 

    } 

public class Field<T> : IField 
    { 
     public string Name { get; set; } 
     public Type Type 
     { 
      get 
      { 
       return typeof(T); 
      } 
     } 
     public int Length { get; set; } 
     public T Value { get; set; } 
    } 

modo da poter scrivere questo codice:

var list = new List<IField>(); 

ora questa lista può contenere qualsiasi oggetto di tipo Field<T>

+1

Qual è il vantaggio di ripetere una risposta esistente? –

+7

C'erano solo 4 minuti tra di loro. Se sei un typ lento come me, potresti non aver notato l'altra risposta. –

+1

Sì, non ho notato l'altra risposta :) – VahiD