我只是分享这个,因为它让我疯狂了一段时间,所以,发布问题和答案以防万一有人遇到同样的情况。
我在我的一个项目中使用反射来从泛型类型中获取值。 问题不在于泛型Type方法调用,而在于实际返回值本身是泛型类型。
由于我事先并不知道泛型类型参数,因此我不能在返回的对象上使用如下所示的解决方案:
method = method.MakeGenericMethod(typeof(SomeClass));
var result = method.Invoke(service, null);
所以,我做的是,使用动态类型,并在返回的对象上调用属性名称。
var method = octx.GetType().GetMethods().First(x => x.Name == nameof(octx.CreateObjectSet)
&& x.DeclaringType == typeof(ObjectContext));
var generic = method.MakeGenericMethod(type);
dynamic value = generic.Invoke(octx, null);// => This is the generic typed return value.
// below, Using dynamic will work, with the pitfal of no compiler checks
EntitySet set = value.EntitySet;
现在,在我决定将代码复制到另一个解决方案之前,这是完全正常的,我正在为Entity Framework创建一个开源扩展库(EntityExtensions)。
在上一个解决方案中运行良好的同一行代码,不再适用于新解决方案!它报告: System.Data.Entity.Core.Objects.ObjectQuery'不包含'EntitySet'的定义
让我疯狂的是,我能够在调试器中查看实际属性! 有一个具有相同名称的属性,但它只是抛出一个关于动态对象上没有这个属性的异常!
为了清楚起见,我把答案写成答案而不是这里。
答案 0 :(得分:1)
我花了很长时间比较两个项目,确保他们使用相同的.Net版本,相同的库,同样的一切;他们是相同的!
最后,我在两个方面的立即窗口中印上了类型定义,并开始比较它们,那时我注意到有一个区别:
IsVisible: true
这让我想到了泛型类型参数,所以我比较了两个项目,并且......结果是新项目类被设置为private,而旧项目类被设置为public。
这使得反射无法读取正确的泛型返回类型,而Visual Studio调试器能够执行此操作。
所以,解决方案只是将类型从私有更改为公共(在这种情况下我能够做到),一切都像魅力一样。
如果遇到同样奇怪的情况,我希望能节省一些时间。