C# 访问私有字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10862747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access private fields
提问by godzcheater
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 make the fields public?
我想得到System.Guid.c。有没有办法访问它,或者我应该只从支柱复制代码并使字段公开?
采纳答案by Chris Baxter
You can use reflection as suggested by Quantic Programming
您可以按照 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:
尽管如果您可以首先将 guid 转换为字节数组,我可能会建议:
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);
回答by Mark Segal
You should try System.Reflection. Here's an example:
您应该尝试System.Reflection。下面是一个例子:
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
}
}
}
回答by drf
While it's possible to do this with reflection, it may be easier to simply retrieve cfrom System.Guid.ToByteArray().
虽然可以通过反射来做到这一点,但简单地c从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.)
由于此方法使用公共和文档化方法,因此版本之间的更改较少。(通常,应避免依赖私有实现细节,因为这些细节可能会因版本而异。)
回答by Bruno Zell
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");

