since yesterday i'm working on a problem and i don't get it yet...
I've got a class with many Methods and decide in Runtime wich Method has to be called. Every of this Methods returns a List with Elements from my Businessobjects.
My Class looks this way:
public class ReflectiveClass {
public List<BO1> DoSomethingWithBO1(int param){
List<BO1> list = new List<BO1>();
//....
return list;
}
public List<BO2> DoSomethingWithBO2(int param){
List<BO2> list = new List<BO2>();
//....
return list;
}
public void Process(){
//...get MethodInfo and so on
List<object> myReturnValue = (List<object>)methodInfo.Invoke(this, new object[]{param});
// here comes the Exception
}
}
So, at Invoking the Method i got a InvalidCastException and the Debugger told me he could not Cast from
System.Collections.Generic.List`1[BO1]
to
System.Collections.Generic.List`1[System.Object]
I wonder why this doesn't work. I thougt if i use a List every Object could be in this List.
I've even tried it with List but same behaviour.
Is it possible to read reflective the Type of the Return-Value of a Method? And can i then create a Generic List with this Returnvalue and cast to this List? This would be wonderfull.
Greetings and many Thanks for your Help! Benni
Well the only solution is to create a new list..
I appreciate all the Answers!
For your information: I've implemented the Strategy Pattern, because it fits really good to my Project.
PS: I love this community, the peoble here help you so quick and with good solutions. Thanks!
Obviously
BO1
derives fromObject
, and you can't castList<Derived>
toList<Base>
. Suppose we have:You can use
IEnumerable<T>
instead.List<_>
needs to be invariant to be statically type-safe. Imagine this compiledUp to this point everything is nice and dandy, but if you now tried to write to the list like so
the runtime would have to throw an exception as the underlying array is not an int array, but a string array. That's why it does not compile in the first place.
Note that contary to generic lists, arrays have been covariant since C# 1.0, probably for Java compatibility. So this indeed compiles:
... but throws an exception at runtime.
IEnumerable<out T>
is covariant inT
in C# 4.0 (therefore theout
). Maybe this would be the more appropriate interface for your purposes.You should really split your class into two different classes, that should implement same interface. Using reflaction here is not a good thing.
Or if you methdods differ only in type of input parameters, make them generic.
If you have behaviour that changes and is determined at runtime, it's ideal for the Strategy pattern. Have a look at http://www.dofactory.com/Patterns/PatternStrategy.aspx