簡體   English   中英

是否可以通過反射獲得屬性的私有 setter?

[英]Is it possible to get a property's private setter through reflection?

我編寫了一個自定義序列化程序,它通過反射設置對象屬性來工作。 可序列化類使用可序列化屬性進行標記,並且所有可序列化屬性也被標記。 例如,以下類是可序列化的:

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

   public string SometthingNotSerializable {get; set;}
}

當序列化器被要求反序列化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});
}

這工作正常,但是,如何使屬性設置器只能由序列化程序訪問? 如果 setter 是私有的:

public string SomethingSerializable {get; private set;}

然后對propertyInfo.GetSetMethod()的調用在序列化程序中返回 null。 有什么方法可以訪問私有 setter 或任何其他方式來確保只有序列化程序可以訪問 setter? 不保證序列化程序在同一個程序集中。

正如您已經知道的,訪問非公共 setter 的一種方法如下:

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

不過,還有另一種方式:

PropertyInfo property = typeof(Type).GetProperty("Property");
// if Property is defined by a base class of Type, SetValue throws
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.

從搜索引擎來到這里?

這個問題特別是關於訪問公共屬性中的非公共設置器。

  • 如果 property 和 setter 都是 public,則只有第一個示例適合您。 要使第二個示例工作,您需要添加BindingFlags.Public標志。
  • 如果該屬性在父類型中聲明並且對您調用GetProperty的類型不可見,您將無法訪問它。 您需要在屬性可見的類型上調用GetProperty (只要屬性本身可見,這不會影響私有 setter。)
  • 如果繼承鏈中的同一屬性有多個聲明(通過new關鍵字),這些示例將針對調用GetProperty的類型立即可見的屬性。 例如,如果類 A 使用public int Property聲明了 Property,而類 B 通過public new int Property重新聲明了 Property,則typeof(B).GetProperty("Property")將返回 B 中聲明的屬性,而typeof(A).GetProperty("Property")將返回 A 中聲明的屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM