Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to access attributes

I am working on a framework that uses some Attribute markup. This will be used in an MVC project and will occur roughly every time I view a specific record in a view (eg /Details/5)

I was wondering if there is a better/more efficient way to do this or a good best practices example.

At any rate, I have an a couple of attributes e.g:

[Foo("someValueHere")]
String Name {get;set;}

[Bar("SomeOtherValue"]
String Address {get;set;}

What is the most efficient way/best practice to look for these attributes/Act on their values?

I am currently doing something like this:

[System.AttributeUsage(AttributeTargets.Property)]
class FooAttribute : Attribute
{

    public string Target { get; set; }

    public FooAttribute(string target)
    {
        Target = target;
    }
}

And in my method where I act on these attributes(simplified example!):

public static void DoSomething(object source)
{
    //is it faster if I make this a generic function and get the tpe from T?
    Type sourceType = source.GetType();

    //get all of the properties marked up with a foo attribute
    var fooProperties =  sourceType
      .GetProperties()
      .Where(p => p.GetCustomAttributes(typeof(FooAttribute), true)
      .Any())
      .ToList();

    //go through each fooproperty and try to get the value set
    foreach (var prop in fooProperties)
    {          
        object value = prop.GetValue(source, null);
        // do something with the value
        prop.SetValue(source, my-modified-value, null);
     }
 }
like image 678
Yablargo Avatar asked Sep 05 '12 03:09

Yablargo


2 Answers

Attribute.GetCustomAttribute and PropertyInfo/MemberInfo.GetCustomAttribute is the recommended way of getting at attribute objects.

Although, I wouldn't normally enumerate all properties with attributes; you generally want to work a particular attribute so you'd just call GetCustomAttribute directly.If you're looking for attributes on any of your properties, enumerating those properties looking for attributes based on GetCustomAttribute() the way you're doing it, is the best way to do it.

like image 157
exacerbatedexpert Avatar answered Oct 25 '22 09:10

exacerbatedexpert


There is not really much choice when dealing with attributes - your code is ok and reasonable as is, it is also unlikley to be your main performance concern. The only immediate thing is to drop ToList call as absolutely unnecessary.


Side notes: performance related question should look approximately

"I've measured my code and portion XXX seems to be taking too much time (YYY) . The time goal for this piece of code is ZZZ. Is my way of doing XXX reasonable/where can I improve it?".

Note that in you case you are missing YYY and ZZZ time portions - so you can't really say if it is slow for your case or not. And you may want to start measurements with DB/other IO bound operations as it more likely to speed up your overall code.

After you figured that this attribute related code is main perfomance issue you can consider some sort of caching of results or even code generation of some sort (either through caching lambdas that would set necessary values or even full blown IL generation).

like image 1
Alexei Levenkov Avatar answered Oct 25 '22 11:10

Alexei Levenkov