在 .Net 中使用私有集初始化属性
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 会变成 Foo 的 IEnumerable 的工作?
编辑 好吧,所以私有修饰符不会阻止反射看到设置器,从答案来看, ExecuteQuery (或者它是数据上下文?) 使用反射来获取属性名称并忽略修饰符。有办法验证吗?我怎么能自己想出这个办法呢? (将反射添加到标签列表中)
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);
}
I have just been using the private modifier because it works and kept me from being stupid with my code, but now that I need to create a new Foo, I've just removed the private modifier from my property. I'm just really curious, why does the ExecuteQuery into an IEnumerable of Foo's work?
EDIT Ok, so the private modifier doesn't keep reflection from seeing the setter, and from the answers, it appears that ExecuteQuery (or is it the data context?) uses reflection to get property names and ignores the modifiers. Is there a way to verify that? How could I have figured that out on my own? (adding reflection to the tag list)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Foo 上创建一个接受“Name”值的构造函数:
现在像这样构造您的 Foo:
编辑(阅读问题的其余部分)
我的猜测是 ExecuteQuery 使用反射来检查类并找到它的属性。它可能并不关心 Name 上的 setter 是私有的 - 只是 Name 根本有一个 setter。
Create a constructor on Foo that accepts a value for "Name":
Now construct your Foo like this:
Edit (read the rest of your question)
My guess is that ExecuteQuery uses reflection to inspect the class and find its properties. It probably doesn't care that the setter on Name is private - only that Name has a setter at all.
下面是说明这种行为的简单代码片段:
Here is simple code snippet that illustrates such behavior:
查询是根据数据存储进行评估的,数据存储没有公共或私有的概念。即使在代码中,也可以使用称为反射的技术来访问私有成员。
The query is evaluated against a data store, which has no concept of public or private. And even in code it is possible to access private members using a technique called Reflection.