2013-08-01 12 views
6

Forse è una domanda da principianti, ma qualcuno potrebbe spiegarmi come sono fatte le classi legate/collegate (non conosco i loro veri nomi)? L'esempio può essere LINQ TO XML.Oggetti/classi collegati/collegati in C# come LINQ

Quando ho il codice sotto:

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

cambio solo element variabile (non ho bisogno di aggiornarlo in doc perché il suo riferimento). Come creare tali classi?

[modifica]
ho provato il codice di @ animaonline e funziona

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

Ma dico qual è la differenza con il codice di cui sopra e al di sotto?

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

esso lools come ti manca la conoscenza di base di come funziona il .NET. Ti suggerisco di leggere un tutorial su valori/tipi di riferimento. – animaonline

+1

Sì, ci ho pensato. Ora so un po 'di più e tutto è chiaro per me :) Grazie per le risposte! – Nickon

+1

prego :) – animaonline

risposta

4

doc.Element è un metodo, restituisce un riferimento al primo elemento figlio (in ordine del documento) con XName specificato.

Considerate questo esempio:

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

Usage:

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

Spiegazione:

Come si può vedere la B() restituisce un riferimento a un elencare l'elemento nella classe A, l'aggiornamento sarà ch ange il valore nella lista A.bs, perché è lo stesso oggetto.

+0

Sì, ma come viene eseguito il metodo 'FirstOrDefault' che restituisce un riferimento? Si restituisce il riferimento B, perché si utilizza 'LINQ'. Voglio scoprire come sono fatte le classi 'LINQ'. – Nickon

+0

E 'stato solo un esempio, non importa fino a quando restituisce un tipo di riferimento si otterrà questo comportamento, non c'è nulla di magico in LINQ. Ho aggiornato la mia risposta .. – animaonline

+0

Per favore, dai un'occhiata alla mia modifica – Nickon

1

I think Capisco cosa stai chiedendo. La validità della mia risposta si basa interamente su questa premessa. : D


I membri della classe non devono essere tipi primitivi, possono essere anche altre classi.

esempio semplice

Date due classi SimpleXDocument e SimpleXElement, notare che SimpleXDocument ha una/proprietà del membro esposto di tipo 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 riferimenti proprio membro del tipo SimpleXElement. Puoi fare cose come:

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

Considera il mio esempio. L'XDocument viene caricato dal file e restituisce un elemento. Quindi se modifico qualcosa in questo elemento, esso ha effetto sull'oggetto XDocument. Ora quando salvi XDocument, le modifiche all'elemento verranno salvate anche. – Nickon

+0

Sì, ne sono a conoscenza. Il mio esempio volutamente semplificato mostrerebbe lo stesso comportamento. L'XDocument nel tuo esempio contiene (almeno uno) membro XElement _somewhere_ nella definizione della classe - questo è tutto creato/istanziato dal metodo .Load(). L'oggetto che "estrai" tramite doc.Element ("...") fa riferimento allo stesso blocco di memoria in cui è archiviato XElement creato su Load() - sono uno e lo stesso, quindi le modifiche a "uno" influiscono su " altro'. –