Is it possible to get or set private fields?
I want to get System.Guid.c
. Is there a way to access it or should I just copy the code from the strut and
You should try System.Reflection. Here's an example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace AccessPrivateField
{
class foo
{
public foo(string str)
{
this.str = str;
}
private string str;
public string Get()
{
return this.str;
}
}
class Program
{
static void Main(string[] args)
{
foo bar = new foo("hello");
Console.WriteLine(bar.Get());
typeof(foo).GetField("str", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(bar, "changed");
Console.WriteLine(bar.Get());
//output:
//hello
//changed
}
}
}
You can have an extension method to get any private field of any type:
public static T GetFieldValue<T>(this object obj, string name) {
var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
return (T)field?.GetValue(obj);
}
And then access a private field of an arbitrary type:
Guid id = Guid.NewGuid();
Int16 c = id.GetFieldValue<Int16>("_c");
You can use reflection as suggested by Quantic Programming
var guid = Guid.NewGuid();
var field= typeof (Guid).GetField("_c", BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
var value = field.GetValue(guid);
Although if you are okay with first converting the guid to a byte array, I might suggest:
var guid = Guid.NewGuid();
var c = BitConverter.ToInt16(guid.ToByteArray(), 6);
The latter approach avoids using reflection.
Edit
You mention needing to be able to set the value as well, you can still avoid reflection:
var guid = Guid.NewGuid();
var guidBytes = guid.ToByteArray();
// get value
var c = BitConverter.ToInt16(guidBytes, 6);
// set value
Buffer.BlockCopy(BitConverter.GetBytes(c), 0, guidBytes, 6, sizeof(Int16));
var modifiedGuid = new Guid(guidBytes);
While it's possible to do this with reflection, it may be easier to simply retrieve c
from System.Guid.ToByteArray()
.
byte[] guid = guid.ToByteArray();
short c = (short)((guid[7] << 8) | guid[6]);
Since this approach uses public and documented methods, it is less subject to change between versions. (In general, relying on private implementation details should be avoided, since these details can change from version to version.)