xximjasonxx
xximjasonxx

Reputation: 1212

Custom Attributes and Type Checking

As I havent seen an answer to this question in my Google and site searches I thought I would pose it the great minds on this site.

As C# does not support generic attributes (which does make sense), I was wondering if there is a way to restrict the type of an argument/property to the attribute based on the type it is decorating. Example:

[AttributeUsage(AttributeTargets.Property)]
public class ColumnBindAttribute : Attribute
{
    public string ColumnName { get; set; }
    public object DefaultValue { get; set; }
}

[ColumnBind(ColumnName = "Category", DefaultValue = "No Category")]
public int CategoryId { get; set; }

Now clearly when I attempt to bind this property to its default value, I will receive a cast error. Curious if there is anyway to enforce the type of DefaultValue to an int or am I limited to a runtime check.

Thanks in advance

Upvotes: 0

Views: 406

Answers (1)

jrista
jrista

Reputation: 32960

As far as I know, there is no way to enforce a type-specific check on a single property of an attribute. However, and let me note that this is not the most elegant solution, you could use polymorphism to your advantage:

[AttributeUsage(AttributeTargets.Property)]
public class ColumnBindAttribute: Attribute
{
    public string ColumnName { get; set; }
    public object DefaultUntypedValue 
    {
        get;
        protected set;
    }
}

[AttributeUsage(AttributeTargets.Property)]
public class ColumnBindGenericAttribute<T> : ColumnBindAttribute
{    
    public T DefaultValue 
    { 
        get { return (T)DefaultUntypedValue; }
        set { DefaultUntypedValue = value; }
    }
}

[AttributeUsage(AttributeTargets.Property)]    
public class ColumnBindInt32Attribute: ColumnBindGenericAttribute<int> {}

[ColumnBindInt32(ColumnName = "Category", DefaultValue = 100)]
public int CategoryId { get; set; }

When retrieving an attribute, the search looks for both the specific type, as well as base types, of the attribute actually applied to the member. You could retrieve all of the ColumBindAttributes decorating a member even if they are derived attributes.

EDIT:

Apologies. The code will not compile if any generic type, directly or indirectly, derives from the Attribute type. That makes the ColumnBindGenericAttribute class impossible. I thought I had found a hole in the compiler...turns out its smarter than me. :P

Upvotes: 2

Related Questions