使用反射和列表的 C# 动态转换
从昨天开始,我正在解决一个问题,但我还不明白......
我有一个包含许多方法的类,并决定在运行时必须调用该方法。每个方法都会返回一个列表,其中包含来自我的 Businessobjects 的元素。
我的类看起来是这样的:
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
}
}
所以,在调用该方法时,我得到了一个 无效转换异常 调试器告诉我他无法从 投射
System.Collections.Generic.List`1[BO1]
到
System.Collections.Generic.List`1[System.Object]
我想知道为什么这不起作用。我想如果我使用列表,每个对象都可以在这个列表中。
我什至尝试过使用 List 但行为相同。
是否可以读取方法返回值的反射类型?然后我可以使用此返回值创建一个通用列表并转换为该列表吗?这太棒了。
问候并非常感谢您的帮助! 本尼
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
显然
BO1
派生自Object
,并且您无法将List
转换为List
。假设我们有:您可以使用
IEnumerable
代替。Obviously
BO1
derives fromObject
, and you can't castList<Derived>
toList<Base>
. Suppose we have:You can use
IEnumerable<T>
instead.如果您的行为会发生变化并在运行时确定,那么它非常适合策略模式。看看 http://www.dofactory.com/Patterns/PatternStrategy.aspx
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
List<_>
需要保持不变才能实现静态类型安全。想象一下编译到此为止一切都很好,但如果你现在尝试写入
像这样的列表,
运行时必须抛出异常,因为底层数组不是 int 数组,而是字符串数组。这就是为什么它一开始就无法编译的原因。
请注意,与通用列表相反,自 C# 1.0 以来数组一直是协变的,
可能是为了 Java 兼容性。所以这确实可以编译:
...但在运行时抛出异常。
IEnumerable
是 C# 4.0 中T
的协变(因此是out
)。也许这将是更适合您的目的的界面。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 can use this :
您确实应该将您的类分成两个不同的类,它们应该实现相同的接口。在这里使用反射并不是一件好事。
或者,如果您的方法仅在输入参数类型上有所不同,请将它们设为通用。
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.
那么唯一的解决方案是创建一个新列表..
Well the only solution is to create a new list..
我感谢所有的答案!
供您参考:我已经实现了策略模式,因为它非常适合我的项目。
PS:我喜欢这个社区,这里的人们可以如此快速地为您提供良好的解决方案。谢谢!
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!