views:

93

answers:

3
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)

+3  A: 

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.

Matt Hamilton
This is correct. You can easily get the private setter method from a `PropertyInfo` using `GetSetMethod(true)`. I'm pretty sure that this is what Linq to SQL does.
Aaronaught
+1  A: 

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.

Morten Mertner
+3  A: 

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"
Igor Zevaka
very helpful, thank-you
Martin Neal