2010-05-07 6 views
5
public class Foo 
{ 
    public string Name { get; private set;} // <-- Because set is private, 
} 

void Main() 
{ 
    var bar = new Foo {Name = "baz"}; // <-- This doesn't compile 
    /*The property or indexer 'UserQuery.Foo.Name' cannot be used 
     in this context because the set accessor is inaccessible*/ 

    using (DataContext dc = new DataContext(Connection)) 
    { 
     // yet the following line works. **How**? 
     IEnumerable<Foo> qux = dc.ExecuteQuery<Foo>(
      "SELECT Name FROM Customer"); 
    } 
    foreach (q in qux) Console.WriteLine(q); 
} 

Je viens en utilisant le modificateur privé, car il fonctionne et m'a empêché d'être stupide avec mon code, mais maintenant que je dois créer un nouveau Foo, je viens retiré le modificateur privé de ma propriété. Je suis juste vraiment curieux, pourquoi ExecuteQuery dans un travail IEnumerable de Foo?propriétés avec des ensembles privés d'initialisation en .Net

EDIT Ok, donc le modificateur privé ne tient pas la réflexion de voir le compositeur, et des réponses, il semble que ExecuteQuery (ou est-ce le contexte de données?) Utilise la réflexion pour obtenir les noms de propriété et ne tient pas compte de la modificateurs. Y a-t-il un moyen de vérifier cela? Comment aurais-je pu le comprendre par moi-même? (En ajoutant la réflexion à la liste des tags)

Répondre

4

Créer un constructeur Foo qui accepte une valeur pour "Nom":

public class Foo 
{ 
    public Foo(string name) 
    { 
     Name = name; 
    } 

    public string Name { get; private set; } 
} 

maintenant construire votre Foo comme ceci:

var bar = new Foo("baz"); 

Modifier (Lire le reste de votre question)

Je suppose que ExecuteQuery utilise la réflexion pour inspecter la classe et trouver ses propriétés. Il ne se soucie probablement pas que le setter sur le nom est privé - seulement ce nom a un setter du tout.

+0

Cela est correct. Vous pouvez facilement obtenir la méthode de setter privé à partir d'un 'PropertyInfo' en utilisant' GetSetMethod (true) '. Je suis à peu près sûr que c'est ce que fait Linq to SQL. – Aaronaught

1

La requête est évaluée par rapport à un magasin de données, qui n'a aucun concept de public ou privé. Et même dans le code, il est possible d'accéder à des membres privés en utilisant une technique appelée Réflexion.

4

est ici extrait de code simple qui illustre ce comportement:

class Blah { 
    public string Property { get; private set; } 
} 

var blah = new Blah(); 
typeof(Blah).GetProperty("Property").SetValue(blah, "newValue", null); 
// at this stage blah.Property == "newValue" 
+0

très utile, merci –