2016-03-21 35 views
5

Desidero avere una classe con diverse classi nidificate, in modo che quando creo una nuova classe genitore, venga creato un oggetto di ogni classe nidificata e posso fare riferimento alle variabili all'interno di ogni classe nidificata globalmente.Riferimento a oggetti di classe annidati in C#

Ecco il mio codice corrente:

public class StockChecklist 
{ 
    public class qty1p1 { public string tag = "uniqueval23456"; public string value = ""; public string reference = ""; } 
    public class qty1p2 { public string tag = "uniqueval3736"; public string value = ""; public string reference = ""; } 

    public class qty2 { public string tag = "uniqueval97357"; public string value = ""; public string reference = ""; } 

    public class qty3p1 { public string tag = "uniqueval88356"; public string value = ""; public string reference = ""; } 
    public class qty3p2 { public string tag = "uniqueval62346"; public string value = ""; public string reference = ""; } 
    public class qty3p3 { public string tag = "uniqueval09876"; public string value = ""; public string reference = ""; } 
    public class qty3p4 { public string tag = "uniqueval62156"; public string value = ""; public string reference = ""; } 

    public class qty4 { public string tag = "uniqueval25326"; public string value = ""; public string reference = ""; } 

}

poi creo un nuovo oggetto padre con:

StockChecklist theCurrentList = new StockChecklist();

Ma come si fa accedere agli oggetti nidificati 'tag', 'valore' e 'di riferimento '? Speravo in qualcosa di semplice come StockChecklist.qty1p1.tag = 'changedval999999999';

È qualcosa del genere possibile con C#?

+1

E 'molto chiaro il motivo per cui * * avete tutte le classi nidificate cripticamente-e-non convenzionale-nome. Puoi dare più contesto per ciò che stai cercando di ottenere?È molto probabile che esista una soluzione migliore. Si noti che la creazione di un'istanza della classe esterna * non * crea automaticamente un'istanza di qualsiasi classe nidificata. –

+0

Puoi trovare la risposta qui https://msdn.microsoft.com/en-us/library/ms173120.aspx –

+1

Puoi usare una classe Dizionario invece di creare 6 classi che hanno lo stesso scopo che è quello di memorizzare alcuni valori –

risposta

7

È mescolato definizione e dichiarazione. La definizione di una classe nidificata non crea un'istanza. Anche le classi che definisci hanno l'aspetto di utilizzare tutte le stesse proprietà. Quindi, dovresti definire una classe e dichiarare più istanze.

È possibile risolvere questo problema con:

C# 6,0

public class Info 
{ 
    public string tag { get; set; } 
    public string value { get; set; } 
    public string reference { get; set; } 

} 

public class StockChecklist 
{ 
    public Info qty1p1 { get; } = new Info { tag = "uniqueval23456", value = "", reference = "" }; 
    public Info qty1p2 { get; } = new Info { tag = "uniqueval3736", value = "", reference = "" }; 

    public Info qty2 { get; } = new Info { tag = "uniqueval97357", value = "", reference = "" }; 

    public Info qty3p1 { get; } = new Info { tag = "uniqueval88356", value = "", reference = "" }; 
    public Info qty3p2 { get; } = new Info { tag = "uniqueval62346", value = "", reference = "" }; 
    public Info qty3p3 { get; } = new Info { tag = "uniqueval09876", value = "", reference = "" }; 
    public Info qty3p4 { get; } = new Info { tag = "uniqueval62156", value = "", reference = "" }; 
    public Info qty4 { get; } = new Info { tag = "uniqueval25326", value = "", reference = "" }; 
} 

Pre C# 6.0 è necessario creare le istanze nel costruttore.

public class StockChecklist 
{ 

    public StockChecklist() 
    { 
     qty1p1 = new Info { tag = "uniqueval23456", value = "", reference = "" }; 
     qty1p2 = new Info { tag = "uniqueval3736", value = "", reference = "" }; 

     qty2 = new Info { tag = "uniqueval97357", value = "", reference = "" }; 

     qty3p1 = new Info { tag = "uniqueval88356", value = "", reference = "" }; 
     qty3p2 = new Info { tag = "uniqueval62346", value = "", reference = "" }; 
     qty3p3 = new Info { tag = "uniqueval09876", value = "", reference = "" }; 
     qty3p4 = new Info { tag = "uniqueval62156", value = "", reference = "" }; 
     qty4 = new Info { tag = "uniqueval25326", value = "", reference = "" }; 
    } 

    public Info qty1p1 { get; private set; } 
    public Info qty1p2 { get; private set; } 

    public Info qty2 { get; private set; } 

    public Info qty3p1 { get; private set; } 
    public Info qty3p2 { get; private set; } 
    public Info qty3p3 { get; private set; } 
    public Info qty3p4 { get; private set; } 
    public Info qty4 { get; private set; } 
} 

nota: Come alcuni commenti già notato, dichiarando 8 istanze della stessa classe all'interno di una classe potrebbe puntare sul design 'poveri'. Potresti creare un Dictionary<> per questo.


Ecco una versione dizionario: (bonus)

public class Info 
{ 
    public string tag { get; set; } 
    public string value { get; set; } 
    public string reference { get; set; } 

} 

public class StockChecklist 
{ 
    private Dictionary<string, Info> _infoDict = new Dictionary<string, Info>(); 

    private void AddToDict(Info info) 
    { 
     _infoDict.Add(info.tag, info); 
    } 

    public StockChecklist2() 
    { 
     AddToDict(new Info { tag = "uniqueval23456", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval3736", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval97357", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval88356", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval62346", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval09876", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval62156", value = "", reference = "" }); 
     AddToDict(new Info { tag = "uniqueval25326", value = "", reference = "" }); 
    } 

    public bool TryGetByTag(string tag, out Info info) 
    { 
     return _infoDict.TryGetValue(tag, out info); 
    } 

    public Info this[string tag] 
    { 
     get 
     { 
      Info info; 

      if (!_infoDict.TryGetValue(tag, out info)) 
       return null; 

      return info; 
     } 
    } 
} 

utilizzarlo come: (C# 6,0)

StockChecklist stock = new StockChecklist(); 
Info info; 
if (stock.TryGetByTag("uniqueval23456", out info)) 
{ 
    Trace.WriteLine($"{info.tag} = {info.value}"); 
} 

O (C# 6.0)

Trace.WriteLine(stock["uniqueval88356"]?.value); 
+0

Sì, questo sembra essere dove stavo andando male . Dovevo solo dichiarare una classe separata, quindi usare quella classe per istanziare oggetti nella mia altra classe. Ho pensato erroneamente che le classi nidificate fossero in qualche modo la risposta all'accesso agli oggetti all'interno della classe – Lee

+0

Ho appena letto l'aggiornamento e la differenza tra le diverse versioni di C#. Era più di quanto avrei mai potuto chiedere. Grazie mille! – Lee

+0

Non mi ero reso conto che avrei potuto usare anche i miei tipi personalizzati con Dizionario! Wow grazie! Sembra qualcosa che dovrò esaminare molto di più – Lee

0

si dovrebbe fare qualcosa di simile:

public class qty1p1 { public string tag = "uniqueval23456"; public string value = ""; public string reference = ""; } 
    public class qty1p2 { public string tag = "uniqueval3736"; public string value = ""; public string reference = ""; } 

    public class qty2 { public string tag = "uniqueval97357"; public string value = ""; public string reference = ""; } 

    public class qty3p1 { public string tag = "uniqueval88356"; public string value = ""; public string reference = ""; } 
    public class qty3p2 { public string tag = "uniqueval62346"; public string value = ""; public string reference = ""; } 
    public class qty3p3 { public string tag = "uniqueval09876"; public string value = ""; public string reference = ""; } 
    public class qty3p4 { public string tag = "uniqueval62156"; public string value = ""; public string reference = ""; } 

    public class qty4 { public string tag = "uniqueval25326"; public string value = ""; public string reference = ""; } 

public class StockChecklist 
{ 
    public qty1p1 _qty1p1; 
    public qty1p2 _qty1p2; 
. 
. 
. 
} 

e quindi è possibile utilizzare le cose come:

StockChecklist theCurrentList = new StockChecklist(); 
theCurrentList._qty1p1.tag = 'changedval999999999'; 
+1

Probabilmente vuoi dire "theCurrentList.qty1p1.tag', no? Inoltre è necessario prima istanziare tali proprietà all'interno di 'StockCheckList'. – HimBromBeere

+0

Sì, certo. Questo è ciò che accade quando copi il codice dalla domanda. si dimentica di modificarlo;) –

+0

esegue ancora in un NRE come '_qty1p1' non è istanziato :) – HimBromBeere

-1

Si può fare in questo modo:

public class Parent 
{ 

    public class child1 { public string name = "a"; public int Value = 1;} 
    public class child2 { public string name = "b"; public int Value = 2;} 
    public class child3 { public string name = "c"; public int Value = 3;} 
    public class child4 { public string name = "d"; public int Value = 4;} 
    public class child5 { public string name = "e"; public int Value = 5;} 
    public child1 c1; 
    public child2 c2; 
    public child3 c3; 
    public child4 c4; 
    public child5 c5; 
    public Parent() { 
     this.c1 = new child1(); 
     this.c2 = new child2(); 
     this.c3 = new child3(); 
     this.c4 = new child4(); 
     this.c5 = new child5(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 

     Parent p1 = new Parent(); 
     Console.WriteLine(p1.c1.name); 
     Console.WriteLine(p1.c2.name); 
     Console.WriteLine(p1.c3.name); 
     Console.WriteLine(p1.c4.name); 
     Console.WriteLine(p1.c5.name); 
     Console.ReadLine(); 

    }