initializing properties with private sets in .Net

时光毁灭记忆、已成空白 提交于 2020-01-14 09:56:06

问题


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)


回答1:


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.




回答2:


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"



回答3:


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.



来源:https://stackoverflow.com/questions/2785551/initializing-properties-with-private-sets-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!