是否有可能通过反思得到一个房产的私人制定者?

Rad*_*ado 22 c# reflection serialization

我编写了一个自定义序列化程序,通过反射设置对象属性.可序列化类用serializable属性标记,所有可序列化属性也被标记.例如,以下类是可序列化的:

[Serializable]
public class Foo
{
   [SerializableProperty]
   public string SomethingSerializable {get; set;}

   public string SometthingNotSerializable {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

当系列化程序被要求反序列化时SomethingSerializable,它获取属性的set方法并使用它来设置它,如下所示:

PropertyInfo propertyInfo; //the property info of the property to set
//...//
if (propertyInfo.CanWrite && propertyInfo.GetSetMethod() != null)
{
   propertyInfo.GetSetMethod().Invoke(obj, new object[]{val});
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是,如何才能使属性设置器只对序列化器可访问?如果setter是私有的:

public string SomethingSerializable {get; private set;}
Run Code Online (Sandbox Code Playgroud)

然后调用propertyInfo.GetSetMethod()在序列化器中返回null.有没有办法访问私有setter或任何其他方式,以确保只有序列化程序可以访问setter?不保证序列化程序在同一个程序集中.

Zen*_*xer 34

正如您已经想到的,访问非公共setter的一种方法如下:

PropertyInfo property = typeof(Type).GetProperty("Property");
property.DeclaringType.GetProperty("Property");
property.GetSetMethod(true).Invoke(obj, new object[] { value });
Run Code Online (Sandbox Code Playgroud)

不过还有另外一种方法:

PropertyInfo property = typeof(Type).GetProperty("Property");
property.DeclaringType.GetProperty("Property");
property.SetValue(obj, value, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);  // If the setter might be public, add the BindingFlags.Public flag.
Run Code Online (Sandbox Code Playgroud)

来自搜索引擎?

这个问题具体是关于访问公共财产中的非公共二传手.

  • 如果属性和setter都是公共的,则只有第一个示例适合您.要使第二个示例起作用,您需要添加BindingFlags.Public标志.
  • 如果属性是在父类型中声明的,并且对于您要调用的类型不可见GetProperty,则您将无法访问它.您需要调用GetProperty属性可见的类型.(只要属性本身可见,这不会影响私有的setter.)
  • 如果继承链中的同一属性有多个声明(通过new关键字),则这些示例将针对GetProperty调用的类型立即可见的属性.例如,如果A类声明Property使用public int Property,而B类重新声明Property via public new int Property,typeof(B).GetProperty("Property")则返回B中声明的属性,同时typeof(A).GetProperty("Property")返回A中声明的属性.

  • 如果Property由Type的基类定义,则SetValue引发。可以通过将其插入两行之间来解决此问题:`property = property.DeclaringType.GetProperty(“ Property”);` (3认同)