在 .Net 中使用私有集初始化属性

发布于 2024-08-31 19:19:51 字数 891 浏览 4 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝天白云 2024-09-07 19:19:51

在 Foo 上创建一个接受“Name”值的构造函数:

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

    public string Name { get; private set; }
}

现在像这样构造您的 Foo:

var bar = new Foo("baz");

编辑(阅读问题的其余部分)

我的猜测是 ExecuteQuery 使用反射来检查类并找到它的属性。它可能并不关心 Name 上的 setter 是私有的 - 只是 Name 根本有一个 setter。

Create a constructor on Foo that accepts a value for "Name":

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

    public string Name { get; private set; }
}

Now construct your Foo like this:

var bar = new Foo("baz");

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.

木有鱼丸 2024-09-07 19:19:51

下面是说明这种行为的简单代码片段:

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"

Here is simple code snippet that illustrates such behavior:

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"
一袭白衣梦中忆 2024-09-07 19:19:51

查询是根据数据存储进行评估的,数据存储没有公共或私有的概念。即使在代码中,也可以使用称为反射的技术来访问私有成员。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文