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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:34:15  来源:igfitidea点击:

Access private fields

c#.netprivate

提问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().

虽然可以通过反射来做到这一点,但简单地cSystem.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");