1

I want to get access to the m_Info field of Uri class to change some fields inside. but uriInfo.GetValue(uri) returns null.

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

the code works fine for my test class with the same structure as Uri but it fails for the System.Uri class. Any ideas?

Radiofisik
  • 150
  • 11
  • What makes you think that the *xamarin / android* version *has* a field called `m_Info`? it is not required to share an implementation with the .NET Framework implementation. And on a protected environment such as android: it is not required to let you have access to the insides *at all*. What is it that returns `null`? is it the `GetField`? or the `GetValue`? – Marc Gravell Jun 22 '17 at 09:05
  • GetField does NOT return null. GetValue does. That makes me think like that. – Radiofisik Jun 22 '17 at 09:14

1 Answers1

2

Quite simply: m_Info isn't assigned in that code-path; it is lazily assigned when first needed. Locally, this works:

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

Note, however, that this approach is itself not fully encompassing; looking in reflector for .Port, this would only apply for "simple syntax" (whatever that means):

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;

The point being: guaranteeing that m_Info has a value is non-trivial. You might want to try invoking the EnsureInfoInfo() method first via reflection.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900