如何通过反射从Underscore开始访问“私有虚拟”属性

时间:2011-07-15 18:42:10

标签: c# .net vb.net

我试图使用Reflection访问以下属性,因为我没有原始源代码(假设这是通过Reflector反编译的)。它似乎是“私人虚拟”或者因为它在属性的开头有“_”的特殊之处。除了这个,我可以访问所有其他私有属性没问题。只是无法弄清楚我做错了什么:

 private virtual String _MyProperty
    {
      get
      {
        return this.__MyProperty;
      }
      [MethodImpl(MethodImplOptions.Synchronized)] set
      {
        this.__MyProperty = "blah";
      }
    }

我尝试使用Reflection访问它,如下所示:

ReflectionHelper.GetPropertyValue(<class of above property>, "_MyProperty")

在我的ReflectionHelper类中使用以下方法:

Public Shared Function GetPropertyValue(ByVal obj As Object, ByVal prop As String) As Object
        Dim objectType As Type = obj.GetType()
        Dim bindingFlags As BindingFlags = bindingFlags.GetProperty Or bindingFlags.Public Or bindingFlags.NonPublic Or bindingFlags.Instance

        Dim propInfo As PropertyInfo = objectType.GetProperty(prop, bindingFlags)
        If propInfo Is Nothing Then
            Throw New Exception("Property: '" & prop & "' not found in: " & objectType.ToString)
        End If
        Return propInfo.GetValue(obj, Nothing)
    End Function

2 个答案:

答案 0 :(得分:5)

private virtual String _MyProperty应该是编译器错误。当我在VS 2010中尝试这个时,我得到“私有方法不能多态”和“虚拟方法不能私有”。

这是有道理的,因为private表示“不能在此类之外访问(包括派生类)”,而virtual表示“可以被派生类覆盖”。如果你可以覆盖派生类中的方法,那么你可以从派生类中调用它,使它不再是私有的。

我想知道你是否正在反编译一些用托管C ++编写的代码。我认为在Visual C ++中可以实现以下功能:

interface class I
{
  property bool IsOk
  {
    bool get();
  }
};

public ref class A abstract : I
{
private:
  virtual property bool IsFine
  {
    bool get() sealed = I::IsOk::get
    {
      return false;
    }
  }
};

编辑:我发现了一个错误报告,提到这是Visual C ++编译器中的错误:https://connect.microsoft.com/VisualStudio/feedback/details/651255/c-cli-property-overriding-and-renaming

答案 1 :(得分:0)

好的我明白了。通过Vlad的问题在原始帖子下面我改变了ReflectionHelper函数“LookThroughAllBaseProperties”,如下所示:

Public Shared Function GetPropertyValue(ByVal obj As Object, ByVal prop As String, Optional ByVal bindFlags As BindingFlags = BindingFlags.GetProperty Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance) As Object
        Dim objectType As Type = obj.GetType()

        Dim propInfo As PropertyInfo = objectType.GetProperty(prop, bindFlags)
        If propInfo Is Nothing Then
            propInfo = LookThroughtAllBaseProperties(objectType, prop, bindFlags)
        End If

        If propInfo Is Nothing Then
            Throw New Exception("Property: '" & prop & "' not found in: " & objectType.ToString)
        End If
        Return propInfo.GetValue(obj, Nothing)
    End Function

    Private Shared Function LookThroughtAllBaseProperties(ByVal objectType As Type, ByVal name As String, ByVal bindFlags As BindingFlags) As PropertyInfo
        Dim objType As Type = objectType
        While objType IsNot Nothing
            For Each availProp As PropertyInfo In objType.GetProperties(bindFlags)
                If availProp.Name = name Then
                    Return availProp
                End If
            Next
            objType = objType.BaseType
        End While
        Return Nothing
    End Function

现在找到该属性。也许现在有人可以解释为什么这样有效......