2016-03-21 14 views
5

Chcę mieć klasę z kilkoma zagnieżdżonymi klasami, tak aby podczas tworzenia nowej klasy nadrzędnej został utworzony obiekt każdej klasy zagnieżdżonej i mogę odwoływać się do zmiennych w obrębie każdej zagnieżdżonej klasy globalnie.Odwołanie zagnieżdżonych obiektów klas w C#

Tu jest mój bieżący kod:

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 = ""; } 

}

następnie utworzyć nowy obiekt nadrzędny z:

StockChecklist theCurrentList = new StockChecklist();

ale w jaki sposób uzyskać dostęp do obiektów zagnieżdżonych 'tag', 'wartości' i „odwołanie "? Miałem nadzieję na coś prostego jak StockChecklist.qty1p1.tag = 'changedval999999999';

Czy coś takiego jest możliwe z C#?

+1

To bardzo niejasny * dlaczego * masz wszystkie te tajemniczo i-niekonwencjonalnie nazwach klas zagnieżdżonych. Czy możesz podać więcej kontekstu dla tego, co próbujesz osiągnąć?Jest bardzo prawdopodobne, że istnieje lepsze rozwiązanie. Zauważ, że tworzenie instancji klasy zewnętrznej nie * tworzy * automatycznie instancji żadnych klas zagnieżdżonych. –

+0

Możesz znaleźć odpowiedź tutaj: https://msdn.microsoft.com/en-us/library/ms173120.aspx –

+1

Możesz użyć klasy Dictionary zamiast tworzyć 6 klas, które mają ten sam cel, jakim jest przechowywanie niektórych wartości –

Odpowiedz

7

można mieszać definicję i deklaracji. Definiowanie klasy zagnieżdżonej nie tworzy instancji. Również zdefiniowane klasy wyglądają tak, jakby wszystkie używały tych samych właściwości. Dlatego powinieneś zdefiniować jedną klasę i zadeklarować wiele instancji.

Można to naprawić z:

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 trzeba tworzyć instancje w konstruktorze.

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; } 
} 

Uwaga: Podobnie jak niektóre komentarze już wspomniano, deklarując 8 wystąpień tej samej klasy w klasie mogłyby wskazywać na „złej” konstrukcji. Możesz utworzyć dla niego Dictionary<>.


Oto wersja słownika: (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; 
     } 
    } 
} 

używać go jak: (C# 6,0)

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

Albo (C# 6.0)

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

Tak, to wydaje się być tam, gdzie szedłem źle . Musiałem tylko zadeklarować oddzielną klasę, a następnie użyć tej klasy do tworzenia instancji obiektów w mojej drugiej klasie. Błędnie myślałem, że zagnieżdżone klasy były w jakiś sposób odpowiedzią na dostęp do obiektów w klasie – Lee

+0

Po prostu przeczytałem twoją aktualizację i różnicę między różnymi wersjami C#. To było więcej, niż mogłem kiedykolwiek poprosić. Dziękuję Ci bardzo! – Lee

+0

Nie wiedziałem, że mogę używać własnych typów niestandardowych ze Słownikiem! Wow, dziękuję! Wygląda na to, że będę musiał zajrzeć dużo więcej. – Lee

0

Powinieneś zrobić coś takiego:

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; 
. 
. 
. 
} 

a następnie można go używać jak:

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

Prawdopodobnie masz na myśli 'theCurrentList.qty1p1.tag', nie twój? Ponadto musisz najpierw utworzyć instancję tych właściwości w 'StockCheckList'. – HimBromBeere

+0

Tak, oczywiście. Tak dzieje się po skopiowaniu kodu z pytania. zapomniałeś go edytować;) –

+0

Ciągle działa w NRE, ponieważ '_qty1p1' nie jest instantiaed :) – HimBromBeere

-1

Można zrobić tak:

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(); 

    }