可以在编译时评估C#自定义属性吗?

时间:2013-05-30 15:56:29

标签: c# .net metaprogramming custom-attributes

我有以下自定义属性:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed public class CLSASafeAttribute : Attribute
{
    public Boolean CLSSafe { get; set; }
    public CLSASafeAttribute(Boolean safe)
    {
        CLSSafe = safe;
    }
}

以下枚举部分:

public enum BaseTypes
{
    /// <summary>
    /// Base class.
    /// </summary>
    [CLSASafe(true)]
    Object = 0,

    /// <summary>
    /// True / false.
    /// </summary>
    [CLSASafe(true)]
    Boolean,

    /// <summary>
    /// Signed 8 bit integer.
    /// </summary>
    [CLSASafe(false)]
    Int8
}

我现在希望能够为每个枚举创建一个唯一的类,并且能够通过查看正在实现的类型将其标记为CLSSafe。我有以下内容,这显然是不正确的,但说明了我的意图:

[CLSASafe((Boolean)typeof(BaseTypes.Object).GetCustomAttributes(typeof(BaseTypes.Object), false))]
sealed public class BaseObject : Field
{
    public Object Value;
}

有没有办法做到这一点(除了手动标记签名外)?

1 个答案:

答案 0 :(得分:1)

我建议您按如下方式定义属性:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed public class CLSASafeAttribute : Attribute {
    public CLSASafeAttribute(Boolean safe) {
        CLSSafe = safe;
    }
    public CLSASafeAttribute(BaseTypes type) {
        CLSSafe = IsCLSSafe(type);
    }
    public Boolean CLSSafe {
        get;
        private set;
    }
    public static bool IsCLSSafe(BaseTypes type) {
        var fieldInfo = typeof(BaseTypes).GetField(typeof(BaseTypes).GetEnumName(type));
        var attributes = fieldInfo.GetCustomAttributes(typeof(CLSASafeAttribute), false);
        return (attributes.Length > 0) && ((CLSASafeAttribute)attributes[0]).CLSSafe;
    }
}

然后,可以使用以下声明:

class Foo {
    [CLSASafe(BaseTypes.Object)] // CLSSafe = true
    object someField1;
    [CLSASafe(BaseTypes.Boolean)] // CLSSafe = true
    bool someField2;
    [CLSASafe(BaseTypes.Int8)] // CLSSafe = false
    byte someField3;
}

或者,无论如何要确定特定字段是否安全:

BaseTypes baseType = GetBaseType(...type of specific field ...);
bool isCLSSafe = CLSASafeAttribute.IsCLSSafe(baseType);