19

プライベート フィールドを取得または設定することは可能ですか?

私は取得したいSystem.Guid.c。それにアクセスする方法はありますか、それともストラットからコードをコピーしてフィールドを公開するだけですか?

4

4 に答える 4

29

Quantic Programming で提案されているように、リフレクションを使用できます

var guid = Guid.NewGuid();
var field= typeof (Guid).GetField("_c", BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
var value = field.GetValue(guid);

最初にguidをバイト配列に変換しても問題ない場合は、次のことをお勧めします。

var guid = Guid.NewGuid();
var c = BitConverter.ToInt16(guid.ToByteArray(), 6);

後者のアプローチでは、リフレクションの使用が回避されます。

編集

値も設定できるようにする必要があると述べていますが、それでもリフレクションを回避できます。

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);
于 2012-06-02T13:54:27.760 に答える
6

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
        }
    }
}
于 2012-06-02T13:48:37.097 に答える
3

リフレクションでこれを行うことは可能ですが、単純にcから取得する方が簡単な場合がありますSystem.Guid.ToByteArray()

byte[] guid = guid.ToByteArray();
short c = (short)((guid[7] << 8) | guid[6]);

このアプローチは公開された文書化された方法を使用するため、バージョン間で変更される可能性は低くなります。(一般に、非公開の実装の詳細に依存することは避けるべきです。これらの詳細はバージョンごとに変わる可能性があるためです。)

于 2012-06-02T13:55:34.687 に答える