Ποια είναι η διαφορά μεταξύ αυτών των δύο παραλλαγών των εκφράσεων αρχικοποίησης συλλογής;

Tagc 09/16/2017. 1 answers, 803 views
c# collection-initializer

Έχω χρησιμοποιήσει το C # για λίγο, αλλά πρόσφατα παρατήρησα ότι η συμπεριφορά μιας από τις δοκιμές της μονάδας μου άλλαξε ανάλογα με την εκδοχή της έκφρασης αρχικοποίησης που χρησιμοποίησα:

  • var object = new Class { SomeCollection = new List { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

Μέχρι αυτό το σημείο υποθέτω ότι η δεύτερη μορφή ήταν απλώς συντακτική ζάχαρη και ήταν σημασιολογικά ισοδύναμη με την πρώτη μορφή. Ωστόσο, η εναλλαγή μεταξύ αυτών των δύο μορφών οδήγησε στη δική μου αποτυχημένη δοκιμή μονάδας να περάσει.

Ο παρακάτω παράδειγμα κώδικας δείχνει αυτό:

 void Main()
{
    var foo1 = new Foo { Items = new List { 1, 2, 3} };
    var foo2 = new Foo { Items = { 1, 2, 3 } };

    foo1.Dump();
    foo2.Dump();
}

class Foo
{
    public List Items { get; set; }
} 

Όταν τρέχω αυτό, η πρώτη ανάθεση λειτουργεί καλά, αλλά η δεύτερη καταλήγει σε μια NullReferenceException .

Το συναίσθημά μου είναι ότι πίσω από τα παρασκήνια ο μεταγλωττιστής αντιμετωπίζει αυτές τις δύο εκφράσεις ως εξής:

 var foo1 = new Foo();
foo1.Items = new List { 1, 2, 3 }; 

var foo2 = new Foo();
foo2.Items.Add(1);
foo2.Items.Add(2);
foo2.Items.Add(3); 

Αυτή η υπόθεση είναι ακριβής;

1 Comments
Leon Barkan 07/31/2017
Αυτό θα σας βοηθήσει: c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

Ναι, η παραδοχή σας είναι ακριβής. Αν ένας αρχικοποιητής αντικειμένου έχει μόνο:

{
    Property = { ... }
} 

προκειμένου

{
    Property = expression
} 

τότε δεν χρησιμοποιείται ο setter για την ιδιότητα - χρησιμοποιείται ο getter και στη συνέχεια ονομάζεται η μέθοδος Add ή οι ιδιότητες ορίζονται εντός της επιστρεφόμενης τιμής. Ετσι:

var foo = new Foo
{
    Collection = { 1 }
    Property =
    {
        Value = 1
    }
}; 

είναι ισοδύναμο με:

// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1; 

Συγκρίνετε αυτό με:

var foo = new Foo
{
    Collection = new List { 1 },
    Property = new Bar { Value = 1 }
}; 

που ισοδυναμεί με:

// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List { 1 };
foo.Property = new Bar { Value = 1 }; 
1 comments
1 Ash Burlaczenko 07/31/2017
Δεν πρέπει να ισοδυναμεί και με τη νέα συλλογή ή απλά προσθέτει;

Related questions

Hot questions

Language

Popular Tags