我有这堂课:
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。我担心这可能是一种副作用,而不是预期的行为,并想知道是否有人可以阐明它的原因。
答案 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