【问题标题】:Set value of private field设置私有字段的值
【发布时间】:2012-10-21 00:44:32
【问题描述】:

为什么下面的代码不起作用:

class Program
{
    static void Main ( string[ ] args )
    {
        SomeClass s = new SomeClass( );

        s.GetType( ).GetField( "id" , System.Reflection.BindingFlags.NonPublic ) // sorry reasently updated to GetField from GetProperty...
            .SetValue( s , "new value" );
    }
}


class SomeClass
{
    object id;

    public object Id 
    {
        get
        {
            return id;
        }
    }   
}

我正在尝试设置私有字段的值。


这是我得到的例外:

 System.NullReferenceException was unhandled   Message=Object reference not set to an instance of an object.   Source=ConsoleApplication7
 StackTrace:
        at Program.Main(String[] args) in C:\Users\Antonio\Desktop\ConsoleApplication7\ConsoleApplication7\Program.cs:line 18
        at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
        at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
        at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
        at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
        at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
        at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
        at System.Threading.ThreadHelper.ThreadStart()   InnerException:

【问题讨论】:

  • 你能指定“不工作”吗?会发生什么,这与您的预期有何不同?您收到任何错误消息吗?
  • 尝试遍历 GetFields()(手动使用调试器断点)以查看返回的内容。 Afaik,不能保证变量 id 将保持命名为 id,但我不确定。另外,我之前在获取私有属性/方法时遇到过问题,通常可以通过使用 BindingFlags.NonPublic | 来解决。 BindingFlags.Public | BindingFlags.Instance(例如)

标签: c# reflection


【解决方案1】:

试试这个(灵感来自Find a private field with Reflection?):

var prop = s.GetType().GetField("id", System.Reflection.BindingFlags.NonPublic
    | System.Reflection.BindingFlags.Instance);
prop.SetValue(s, "new value");

我的更改是使用 GetField 方法 - 您访问的是字段而不是属性,并且使用 Instance 访问或 NonPublic

【讨论】:

  • 不幸的是,这不适用于结构。它接缝设置发送到 SetValue 的结构副本的值,并且原始结构保持不变。
  • 根据 Jon Skeet 的说法,设置结构的正确方法需要在调用 SetValue 之前显式装箱:stackoverflow.com/questions/6280506/…
【解决方案2】:

显然,添加BindingFlags.Instance 似乎已经解决了它:

> class SomeClass
  {
      object id;

      public object Id
      {
          get
          {
              return id;
          }
      }
  }
> var t = typeof(SomeClass)
      ;
> t
[Submission#1+SomeClass]
> t.GetField("id")
null
> t.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
> t.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
[System.Object id]
> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2017-08-31
    相关资源
    最近更新 更多