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

时间:2010-05-07 01:07:30

标签: c# linq reflection private

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);
}

我刚刚使用私有修饰符,因为它的工作方式使我不会对我的代码感到愚蠢,但现在我需要创建一个新的Foo,我刚从我的属性中删除了私有修饰符。我真的很好奇,为什么ExecuteQuery会成为一个有关Foo的IEnumerable的工作?

编辑好的,所以私有修饰符不会反映看到setter,并且从答案中看来,ExecuteQuery(或者它是数据上下文?)使用反射来获取属性命名并忽略修饰符。有没有办法验证?我怎么能自己想出来? (将反射添加到标签列表中)

3 个答案:

答案 0 :(得分:4)

在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。

答案 1 :(得分:4)

以下是说明此类行为的简单代码段:

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"

答案 2 :(得分:1)

针对数据存储评估查询,该数据存储没有公共或私有的概念。即使在代码中,也可以使用名为Reflection的技术访问私有成员。