инициализация свойств с частными наборами в .Net - PullRequest
5 голосов
/ 07 мая 2010
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);
}

Я только что использовал модификатор private, потому что он работает и не позволяет мне быть глупым с моим кодом, но теперь, когда мне нужно создать новый Foo, я только что удалил модификатор private из своего свойства. Мне просто очень любопытно, почему ExecuteQuery превращает IEnumerable в работу Foo?

РЕДАКТИРОВАТЬ Хорошо, поэтому закрытый модификатор не препятствует отражению видеть установщик, и из ответов получается, что ExecuteQuery (или это контекст данных?) Использует отражение для получения имен свойств и игнорирует модификаторы. Есть ли способ проверить это? Как я мог понять это самостоятельно? (добавление отражения в список тегов)

Ответы [ 3 ]

4 голосов
/ 07 мая 2010

Вот простой фрагмент кода, который иллюстрирует такое поведение:

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"
4 голосов
/ 07 мая 2010

Создайте конструктор в Foo, который принимает значение для «имени»:

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

    public string Name { get; private set; }
}

Теперь создайте свой Foo следующим образом:

var bar = new Foo("baz");

Редактировать (прочитайте остальную часть вашего вопроса)

Я предполагаю, что ExecuteQuery использует отражение для проверки класса и поиска его свойств.Вероятно, не важно, что установщик для Name является личным - только у этого Name вообще есть установщик.

1 голос
/ 07 мая 2010

Запрос оценивается по отношению к хранилищу данных, которое не имеет понятия общего или частного. И даже в коде можно получить доступ к закрытым членам, используя технику, которая называется Reflection.

...