2017-06-22 74 views
1

我想訪問Uri類的m_Info字段以更改內部的某些字段。但是uriInfo.GetValue(uri)返回null。Uri類的反射GetValue失敗

 var uri = new Uri("https://stackoverflow.com/questions/12993962/set-value-of-private-field"); 
     var uriInfo = typeof(Uri).GetField("m_Info", BindingFlags.NonPublic | BindingFlags.Instance); 
     var infoField = uriInfo.GetValue(uri); 

代碼工作正常,我有相同的結構,開放的測試類,但它失敗了的System.Uri類。有任何想法嗎?

+0

是什麼讓你認爲* xamarin/android *版本*有一個名爲'm_Info'的字段?它不需要與.NET Framework實現共享一個實現。在受保護的環境(如android)上:不需要讓您訪問內部*。什麼是返回'null'?它是'GetField'嗎?或'GetValue'? –

+0

GetField不會返回null。 GetValue。這讓我這樣想。 – Radiofisik

回答

2

很簡單:m_Info在該代碼路徑中未被分配;它是懶洋洋地分配當第一次需要。在當地,這個工程:

object infoField = uriInfo.GetValue(uri); // null 
var port = uri.Port; // forces it to initialize 
infoField = uriInfo.GetValue(uri); // not null 

但是請注意,這種方法是本身尚未完全涵蓋;尋找在反射器.Port,這將只適用於「簡單的語法」(這意味着什麼):

if (this.m_Syntax.IsSimple) 
{ 
    this.EnsureUriInfo(); 
} 
else 
{ 
    this.EnsureHostString(false); 
} 
if (this.InFact(Flags.HostNotParsed | Flags.NotDefaultPort)) 
{ 
    return this.m_Info.Offset.PortValue; 
} 
return this.m_Syntax.DefaultPort; 

問題的關鍵是:低保m_Info有一個值是不平凡的。您可能想先嚐試通過反射調用EnsureInfoInfo()方法。