Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initializing properties with private sets in .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);
}

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)

like image 989
Marty Neal Avatar asked May 07 '10 01:05

Marty Neal


2 Answers

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.

like image 57
Matt Hamilton Avatar answered Oct 15 '22 15:10

Matt Hamilton


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"
like image 45
Igor Zevaka Avatar answered Oct 15 '22 17:10

Igor Zevaka