2012-10-21 25 views
18

的價值,爲什麼不工作下面的代碼:設置私有字段

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; 
     } 
    } 
} 

我想設置一個私有字段的值。


這裏是exeption我得到:

System.NullReferenceException了未處理消息=對象引用 不設置爲一個對象的一個​​實例。源= ConsoleApplication7
堆棧跟蹤: 在Program.Main(字串[] args)在C:\用戶\安東尼奧\桌面\ ConsoleApplication7 \ ConsoleApplication7 \的Program.cs:線在System.AppDomain._nExecuteAssembly(RuntimeAssembly組件,字符串[] 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.Executi onContext.Run(執行上下文的ExecutionContext,ContextCallback回調,對象狀態) 在System.Threading.ThreadHelper.ThreadStart()的InnerException:

+0

你能指定「不工作」嗎?會發生什麼,以及這與預期的有何不同?你有任何錯誤信息? – Guffa

+0

嘗試通過GetFields()(手動使用調試器斷點)來查看返回的內容。 Afaik,並不能保證變量ID會保持命名ID,但我不確定。另外,我在使用私有屬性/方法之前遇到了問題,通常通過使用BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance(例如) – Alxandr

回答

38

嘗試這(通過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方法 - 你交流設立一個領域而不是一個財產,並與InstanceNonPublic

+0

+1 - BindingFlags.Instance就是答案。 –

+0

不幸的是,這不適用於結構。 它將接收到的結構副本的值設置爲SetValue,原始結構保持不變。 – SoLaR

1

顯然,加入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] 
>