0

クラスとクラス内のプロパティに適用する属性の次のコードがあります。

public class SerialiseAttribute : Attribute, IAspectProvider, IValidableAnnotation {

    public string ApplyToProperty { get; set; }

    public string Name { get; set; }

    public bool Ignore { get; set; }

    bool IValidableAnnotation.CompileTimeValidate(object target) { return true; }

    IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement) {
        var type = targetElement as Type;

        if (type != null && !FastSerialisationCacheAttribute.AppliedTo.Contains(type)) {
            FastSerialisationCacheAttribute.AppliedTo.Add(type);
            yield return new AspectInstance(type, new FastSerialisationCacheAttribute());
        }
    }

}

これにより、FastSerialisationCacheAttribute が初期化され、CompileTimeInitialize が正常に実行されます (TypeLevelAspect アスペクトから派生します)。ただし、生成されたILを確認すると; 提供された型には FastSerialisationCacheAttribute がなく、実行時にリフレクションを使用して見つけることもできません。

このコードで ProviderAspects 関数を切り替えると:

IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement) {
    var type = targetElement as Type;

    if (type != null && !FastSerialisationCacheAttribute.AppliedTo.Contains(type)) {
        FastSerialisationCacheAttribute.AppliedTo.Add(type);
        var constructor = typeof(FastSerialisationCacheAttribute).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
        var objectConstruction = new ObjectConstruction(constructor);
        var introduceCacheAspect = new CustomAttributeIntroductionAspect(objectConstruction);
        yield return new AspectInstance(type, introduceCacheAspect);
    }
}

次に、属性を IL に追加しますが、これは属性を初期化しません (CompileTimeInitialize を実行します)。

4

1 に答える 1