サーチ…


アセンブリとは何ですか?

アセンブリは、 共通言語ランタイム(CLR)アプリケーションのビルディングブロックです。定義したすべての型は、そのメソッド、プロパティ、およびバイトコードとともに、アセンブリ内でコンパイルされ、パッケージ化されます。

using System.Reflection;

Assembly assembly = this.GetType().Assembly;   

アセンブリは、型、メソッド、およびILコードだけでなく、コンパイル時および実行時の両方で、検査および消費に必要なメタデータも含みます。

Assembly assembly = Assembly.GetExecutingAssembly();

foreach (var type in assembly.GetTypes())
{
    Console.WriteLine(type.FullName);
}

アセンブリには、完全で一意のIDを表す名前が付けられます。

Console.WriteLine(typeof(int).Assembly.FullName);
// Will print: "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

この名前にPublicKeyToken含まれている場合、その名前はPublicKeyToken な名前と呼ばれます。アセンブリの厳密な命名は、アセンブリで配布された公開鍵に対応する秘密鍵を使用して署名を作成するプロセスです。このシグネチャは、アセンブリを構成するすべてのファイルの名前とハッシュを含むアセンブリマニフェストに追加され、そのPublicKeyTokenは名前の一部になります。同じ強力な名前を持つアセンブリは同一である必要があります。バージョニングには強力な名前が使用され、アセンブリの競合を防止します。

リフレクションを使用してTのオブジェクトを作成する方法

デフォルトコンストラクタの使用

T variable = Activator.CreateInstance(typeof(T));

パラメータ化されたコンストラクタの使用

T variable = Activator.CreateInstance(typeof(T), arg1, arg2);

リフレクションを使用したオブジェクトの作成とプロパティの設定

プロパティーを持つClassyクラスがあるとしましょう

public class Classy
{
    public string Propertua {get; set;}
}

反映を使ってPropertuaを設定する:

var typeOfClassy = typeof (Classy);
var classy = new Classy();
var prop = typeOfClassy.GetProperty("Propertua");
prop.SetValue(classy, "Value");

リフレクション付きの列挙型の属性を取得する(およびキャッシングする)

属性は、enumのメタデータを示すのに便利です。これの価値を得ることは遅くなる可能性があるので、結果をキャッシュすることが重要です。

    private static Dictionary<object, object> attributeCache = new Dictionary<object, object>();

    public static T GetAttribute<T, V>(this V value)
        where T : Attribute
        where V : struct
    {
        object temp;

        // Try to get the value from the static cache.
        if (attributeCache.TryGetValue(value, out temp))
        {
            return (T) temp;
        }
        else
        {
            // Get the type of the struct passed in.
            Type type = value.GetType();   
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // Get the custom attributes of the type desired found on the struct.
            T[] attribs = (T[])fieldInfo.GetCustomAttributes(typeof(T), false);

            // Return the first if there was a match.
            var result = attribs.Length > 0 ? attribs[0] : null;

            // Cache the result so future checks won't need reflection.
            attributeCache.Add(value, result);

            return result;
        }
    }

リフレクションで2つのオブジェクトを比較する

public class Equatable
{
    public string field1;

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;

        var type = obj.GetType();
        if (GetType() != type)
            return false;

        var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        foreach (var field in fields)
            if (field.GetValue(this) != field.GetValue(obj))
                return false;

        return true;
    }

    public override int GetHashCode()
    {
        var accumulator = 0;
        var fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        foreach (var field in fields)
            accumulator = unchecked ((accumulator * 937) ^ field.GetValue(this).GetHashCode());

        return accumulator;
    }
}

注:この例では、単純化のためにフィールドベースの比較を行っています(静的フィールドとプロパティを無視します)。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow