2013-08-01 9 views
6

Może to pytanie początkującego, ale czy ktoś mógłby mi wytłumaczyć, jak są wykonane powiązane/połączone klasy (nie znam ich prawdziwych nazw)? Przykładem może być LINQ TO XML.Związane/powiązane obiekty/klasy w języku C# podobne do LINQ

Kiedy mam pod kodem:

XDocument doc = XDocument.Load("..."); 
XElement element = doc.Element("root"); 
element.SetAttribute("NewAttribute", "BlahBlah"); 
doc.Save("..."); 

zmienić tylko element zmiennej (nie trzeba go zaktualizować w doc ponieważ jego odwołanie). Jak stworzyć takie klasy?

[edytuj]
Próbowałem kodu @ animaonline i działa

A a = new A(); 
B b = a.B(0); 
b.Name = "asd"; 
Console.WriteLine(a.Bs[0].Name); // output "asd" 

Ale powiedzieć jaka jest różnica z kodem powyżej i poniżej?

List<string> list = new List<string>(); 
list.Add("test1"); 
list.Add("test2"); 
var test = list.FirstOrDefault(); 
test = "asdasda"; 
Console.WriteLine(list[0]); // output "test1" - why not "asdasda" if the above example works??? 
+0

to lools jakbyś brakuje podstawowej wiedzy o tym, jak działa .NET. Sugeruję przeczytanie samouczka na temat typów wartości/referencji. – animaonline

+1

Tak, zająłem się tym. Teraz wiem trochę więcej i wszystko jest dla mnie jasne :) Dzięki za odpowiedzi! – Nickon

+1

Nie ma za co. :) – animaonline

Odpowiedz

4

doc.Element jest metodą, zwraca odniesienie do pierwszego elementu potomnego (w kolejności dokumentu) z podanym XName.

Rozważmy następujący przykład:

public class A 
{ 
    public A() 
    { 
     this.Bs = new List<B>(); 

     this.Bs.Add(new B { Name = "a", Value = "aaa" }); 
     this.Bs.Add(new B { Name = "b", Value = "bbb" }); 
     this.Bs.Add(new B { Name = "c", Value = "ccc" }); 
    } 

    public List<B> Bs { get; set; } 

    public B B(int index) 
    { 
     if (this.Bs != null && this.Bs[index] != null) 
      return this.Bs[index]; 

     return null; 
    } 
} 

public class B 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

Zastosowanie:

A a = new A(); 
var refToA = a.B(0); 
refToA.Value = "Some New Value"; 

foreach (var bs in a.Bs) 
    System.Console.WriteLine(bs.Value); 

Objaśnienie:

Jak widać B() Metoda zwraca odniesienie do element listy w klasie A, aktualizując go będzie ch ange również wartość na liście A.bs, ponieważ jest to ten sam obiekt.

+0

Tak, ale w jaki sposób tworzona jest metoda 'FirstOrDefault', która zwraca referencję? Zwracasz odwołanie B, ponieważ używasz 'LINQ'. Chcę się dowiedzieć, w jaki sposób tworzone są klasy "LINQ". – Nickon

+0

To był tylko przykład, nie ma znaczenia, dopóki zwraca typ odniesienia otrzymasz to zachowanie, nie ma nic magicznego w LINQ. Zaktualizowałem moją odpowiedź .. – animaonline

+0

Proszę spojrzeć na moją edycję – Nickon

1

I think Rozumiem, o co pytasz. Ważność mojej odpowiedzi jest całkowicie oparta na tej przesłance. : D


Członkowie klasy nie muszą być typami pierwotnymi - mogą to być również inne klasy.

Prosty przykład

Biorąc pod uwagę dwie klasy SimpleXDocument i SimpleXElement pamiętać, że SimpleXDocument ma człon/odsłoniętą właściwość typu SimpleXElement:

public Class SimpleXDocument 
{ 
    private SimpleXElement _element; 
    public SimpleXDocument(){ this._element = null;} 
    public SimpleXDocument(SimpleXElement element){this._element = element;} 
    public SimpleXElement Element 
    { 
     get{return this._element;} 
     set{this._element = value;} 
    } 
} 

Public Class SimpleXElement 
{ 
    private String _value; 
    public SimpleXElement(){this._value = String.Empty;} 
    public SimpleXElement(String value){this._value = value;} 
    public String Value 
    { 
     get{return this._value;} 
     set{this._value = value;} 
    } 
} 

SimpleXDocument referencje własnego członka typu SimpleXElement. Możesz zrobić rzeczy takie jak:

SimpleXDocument doc = new SimpleXDocument(); 
doc.Element = new SimpleXElement("Test 1"); 
SimpleXElement element = new SimpleXElement(); 
element.Value = "Test 2"; 
doc = New SimpleXDocument(element); 
SimpleXElement anotherElement = new SimpleXElement("another test"); 
doc.Element = anotherElement; 
doc.Element.Value = "yet another test"; 
anotherElement.Value = "final test"; //N.B. this will update doc.Element.Value too! 
+0

Rozważ mój przykład. XDocument jest ładowany z pliku i zwraca element. Następnie, jeśli zmienię coś w tym elemencie, wpłynie to na obiekt XDocument. Teraz, gdy zapiszę XDocument, zmiany w elemencie zostaną zapisane również. – Nickon

+0

Tak, jestem tego świadomy. Mój celowo uproszczony przykład będzie wykazywał takie samo zachowanie. XDocument w twoim przykładzie zawiera (przynajmniej jeden) element XElement _somewhere_ w definicji klasy - to wszystko jest tworzone/tworzone instancją przez metodę .Load(). Obiekt, który "wyciągasz" przez doc.Element ("...") odnosi się do tego samego kawałka pamięci, w którym zapisany jest XElement utworzony w funkcji Load() - są one jednym i tym samym, dlatego zmiany na "jeden" wpływają na " inny'. –