使用私人访问者设置属性值

时间:2014-10-09 07:46:17

标签: c# .net

我有这堂课:

public class Foo
{
    public string Name { get; private set; }
}

如果我写这个:

Foo foo = new Foo();
foo.Name = "Nocigar";

显然,我遇到了编译器错误。但如果我写这个:

static void Main()
{
    Foo foo = new Foo();

    Action<Foo, string> act = Build();
    act(foo, "Woot");

    Debug.WriteLine(foo.Name);
}

static Action<Foo, string> Build()
{
    ParameterExpression fooParam =
        Expression.Parameter(typeof(Foo),
        "foo");

    ParameterExpression nameParam =
        Expression.Parameter(typeof(string),
        "name");

    MemberExpression propertyValue =
        Expression.Property(fooParam,
        "Name");

    BinaryExpression assignExpression =
        Expression.Assign(propertyValue,
        nameParam);

    LambdaExpression lambda =
        Expression.Lambda(typeof(Action<Foo, string>),
        assignExpression,
        fooParam,
        nameParam);

    return (Action<Foo, string>)lambda.Compile();
}

编译并运行没有问题,编写&#34; Woot&#34;到调试窗口。是什么给了什么?

我打算在某些代码中使用此功能来从数据读取器映射到POCO。我担心这可能是一种副作用,而不是预期的行为,并想知道是否有人可以阐明它的原因。

1 个答案:

答案 0 :(得分:2)

这不是副作用。您可以使用反射或表达式访问此类私人成员,例如:

var dateTimeType = typeof (DateTime);
MethodInfo[] privateMthods = dateTimeType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
privateMthods.ToList().ForEach(a=> Console.WriteLine(a.Name.ToString()));

正如Kevin Hazzard和Jason Bock在“.NET中的元编程”一书中所写的

“还有一个NonPublic值,这意味着你可以看到 通过Reflection API提供私有和受保护的内容。根据您的观点,这个 当您认为这允许任意时,可能看起来像是严重的安全漏洞 用于更改对象中私有字段值的代码。但只有特权代码才能 使用反射调用。如果您没有此级别的访问权限,您将使用反射 失败。“ - 第46页

你也可以考虑这个(再次来自上面提到的书):

“您可能已经猜到了Windows 8应用程序及其安全性 模型,你只能访问公共成员;你无法访问私人会员。再次, 这些更改严格适用于Windows 8应用程序。如果你的目标是.NET 4.5 在Windows 8中,您仍然可以使用完整的Type类。“ - 第318页

这篇文章也很有帮助: Security Considerations for Reflection