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);
}
Я просто использовал частный модификатор, потому что он работает и помешал мне быть глупым с моим кодом, но теперь, когда я должен создать новое Нечто, я только что удалил частный модификатор из своего свойства. Мне просто действительно любопытно, почему делает ExecuteQuery в IEnumerable работы Нечто?
ОТРЕДАКТИРУЙТЕ хорошо, таким образом, частный модификатор не мешает отражению видеть метод set, и из ответов, кажется, что ExecuteQuery (или действительно ли это - контекст данных?) использует отражение для получения имен свойства и игнорирует модификаторы. Существует ли способ проверить это? Как я, возможно, понял это самостоятельно? (добавление отражения к списку тега)
Создайте конструктор на Foo, который принимает значение для «Name»:
public class Foo
{
public Foo(string name)
{
Name = name;
}
public string Name { get; private set; }
}
Теперь создайте свой Foo следующим образом:
var bar = new Foo("baz");
Edit ( прочтите оставшуюся часть вашего вопроса)
Я предполагаю, что ExecuteQuery использует отражение для проверки класса и поиска его свойств. Вероятно, его не волнует, что сеттер для Name является частным - только это имя вообще имеет сеттер.
Запрос оценивается по хранилищу данных, в котором нет понятия public или private. И даже в коде можно получить доступ к частным членам, используя технику, называемую отражением.
Вот простой фрагмент кода, иллюстрирующий такое поведение:
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"