CaffeinatedCM
CaffeinatedCM

Reputation: 764

Dynamic casting issue

I've been looking for a solution to an issue I've been having and as soon as I thought I found a fix it doesn't work. The problem is I have an array of CustomAttriburte and I want to cast them to their actual type so I can have each one passed to a different method depending on their types. For instance: I have a seperate method for RangeAttribute and DisplayFormatAttribute and I want the correct method to be called.

I did a test console application where I had a base class and 2 child classes and they each had their own respective "DoSomething(T t)" Method. By running the method as: "DoSomething(x as dynamic)" the proper method got called for each element in my array.

The following works:

class Base{} 
class ChildA : Base {}
class ChildB : Base {}
class Program {
    static void Main(string[] args) 
    {
        Base[] c = { new ChildA(), new Base(), new ChildB() };
        Console.Out.WriteLine(DoSomething(c[0] as dynamic));
        Console.Out.WriteLine(DoSomething(c[1] as dynamic));
        Console.Out.WriteLine(DoSomething(c[2] as dynamic));
        Console.ReadLine();
     }
     static string DoSomething(Base b) { return "Base";}
     static string DoSomething(ChildA c) { return "ChildA";}
     static string DoSomething(ChildB c) { return "ChildB";}
}

This results in the output I wanted:

ChildA
Base
ChildB

So this works, but in my actual application I get a RuntimeBinderException

My code there is:

class Seeder {
     public void Seed() {
              ... 
             CustomAttributeData[] custAtrData = propertyInfo.CustomAttributes.ToArray();
             for(int i = 0; i < custAtrData.Length; i++) {
                    custAtrData[i] = Behavior.Bug(custAtrData[i] as dynamic);
             }
     }
}
class Behavior {
       public static RangeAttribute Bug(RangeAttribute) {... } 
       public static DisplayAttribute Bug(DisplayAttribute) {...} 
       ... 
}

The exception says the best overload for the method Bug has some invalid arguments, but there is only one argument and I've verified that argument does match an overload for the Bug method.

So why did this work in my test app but not the actual one?

Upvotes: 2

Views: 130

Answers (1)

SLaks
SLaks

Reputation: 887205

CustomAttributeData is a separate class that holds the basic metadata about an attribute from the assembly.

It does not run the actual attribute code and is not an instance of the attribute class.

You want GetCustomAttributes(), which instantiates and returns your actual attribute classes.


Also, you should avoid using dynamic like that; it's rather slow.

Instead, you can simply make all of your attributes inherit a base class or interface, then put the methods in the attribute classes themselves and call them directly via the base type.

Upvotes: 6

Related Questions