一个.net core 反射问题

ly_bin 2018-04-24 06:17:43
情况如下:
定义一个组件接口,

public interface IComponent{}

定义一个启动器基类:

public abstract class Boostraper{
/// <summary>
/// 获取平台组件
/// </summary>
/// <returns></returns>
public virtual IEnumerable<IPlatformComponent> GetComponents()
{
return Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll").Select(Assembly.LoadFile)
.SelectMany(m => m.GetTypes()).Select(m => m.GetTypeInfo())
.Where(m => !m.IsAbstract
&& !m.IsInterface
&& typeof(IComponent).GetTypeInfo().IsAssignableFrom(m))
.Select(Activator.CreateInstance).Cast<IPlatformComponent>();
}
}

接着定义一个日志组件

public interface LogComponent:IComponent{}


以上代码是可以正常运行的,现在问题来了,我在另外一个单元测试项目调用此方法时发现,如果我上面代码加的判断是是

typeof(IComponent).GetTypeInfo().IsAssignableFrom(m)

那么返回IEnumerable<IPlatformComponent>是有值的,一旦使用ToList()方法,完全就没有值。

如果我使用(当然这不符合我要实现的效果)

typeof(object).GetTypeInfo().IsAssignableFrom(m)

那么就不会出现这种问题。

这个问题我暂时无法用简短的语言描述,只好在此求助大家。
我使用的版本为.NET CORE 2.0,是编译器有BUG还是.NET CORE对于反射有了其他的使用方法呢?望解答
...全文
584 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ly_bin 2018-04-25
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
linq 是延迟加载的。所以什么叫做“返回IEnumerable<IPlatformComponent>是有值的”呢?其实这个时候根本返回的就是 Linq 的表达式,并没有开始执行这个表达式啊?!!!
思考了一下,当时我应该就下意识认为调试器出来的值就是该linq的值,而不是不是写错了,是我基础的不牢靠。
引用 5 楼 hanjun0612 的回复:
[quote=引用 2 楼 lybmann 的回复:] 并不是这个问题 IsAssignableFrom是确定指定类型的实例是否可以分配给当前类型的实例。也就是说应当是判断父类型是否可指向子类型。 详见msdn,https://msdn.microsoft.com/zh-cn/library/system.type.isassignablefrom.aspx。 我的问题是为什么迭代器的时候能够查询到实例,而一ToList()转为内存对象时候就没有东西了。
当时我也是看了msdn的解释,但是发现代码写出来就是和解释的不太一样。 但是我也没有深究原因 你可以先试试反过来看看结果, 如果还不行,那我们在讨论tolist的问题。这是当时我写的测试代码 https://blog.csdn.net/hanjun0612/article/details/80068832 [/quote] 实验了一下,的确不是这个地方使用错误的原因, 原本设计是在应用时候决定使用那些组件,目前已经绕过这个点,不过错误原因找不到,有点如鲠在喉,我确认在调试器解析linq时能够解析到对应的组件类型,但是ToList()方法执行后却没有,我想过多种可能性。目前自己也先慢慢验证,不过如果不耗时间,也请大家帮忙解答一下
正怒月神 2018-04-25
  • 打赏
  • 举报
回复
引用 2 楼 lybmann 的回复:
并不是这个问题 IsAssignableFrom是确定指定类型的实例是否可以分配给当前类型的实例。也就是说应当是判断父类型是否可指向子类型。 详见msdn,https://msdn.microsoft.com/zh-cn/library/system.type.isassignablefrom.aspx。 我的问题是为什么迭代器的时候能够查询到实例,而一ToList()转为内存对象时候就没有东西了。
当时我也是看了msdn的解释,但是发现代码写出来就是和解释的不太一样。 但是我也没有深究原因 你可以先试试反过来看看结果, 如果还不行,那我们在讨论tolist的问题。这是当时我写的测试代码 https://blog.csdn.net/hanjun0612/article/details/80068832
  • 打赏
  • 举报
回复
比如说我写代码
var s = "affadfafas";
var query = s.Where(x => x > 'a' && x < 'm');
var result = string.Join("", query);
你能说 query 就是查询出来的结果吗?
  • 打赏
  • 举报
回复
linq 是延迟加载的。所以什么叫做“返回IEnumerable<IPlatformComponent>是有值的”呢?其实这个时候根本返回的就是 Linq 的表达式,并没有开始执行这个表达式啊?!!!
ly_bin 2018-04-25
  • 打赏
  • 举报
回复
并不是这个问题 IsAssignableFrom是确定指定类型的实例是否可以分配给当前类型的实例。也就是说应当是判断父类型是否可指向子类型。 详见msdn,https://msdn.microsoft.com/zh-cn/library/system.type.isassignablefrom.aspx。 我的问题是为什么迭代器的时候能够查询到实例,而一ToList()转为内存对象时候就没有东西了。
正怒月神 2018-04-24
  • 打赏
  • 举报
回复
反一反 m.GetTypeInfo().IsAssignableFrom(typeof(IComponent))
.NET Core前后端分离快速开发框架源码(Core.3.1+AntdVue) 注意:不带技术支持,有帮助文件,虚拟商品,发货不退,看好再拍。 开发环境: 操作系统:Windows 10 后端开发工具:Visual Studio 2019+ 前端开发工具:Visual Studio Code,安装nodejs,yarn SDK:安装.NET Core SKD 3.0 及以上 数据库:SQLServer2012及以上 本框架为.NET Core3.1+Ant Design Vue版 本框架旨在极大的提高开发效率 使用技术栈: 后端:采用.NET Core平台,ASP.NET Core3.1,C#语言(使用反射等高级技术),Entity FrameworkCore(数据库ORM框架)。 使用数据仓储模式,抽象化数据库操作(CRUD等)、支持事务处理以及分布式事务处理(跨库) 支持数据库读写分离、分库分表及事务(仅支持单表操作,不支持多表) 全面采用Autofac作为IOC容器,面向接口编程,全面解耦 集成多种工具类库以及操作拓展 数据库:支持SqlServer,PostgreSQL,MySQL,Oracle(框架使用简单工厂,工厂方法,抽象工厂,可轻松更换数据库),Redis作为分布式缓存 前端:Vue2.x全家桶+Ant Design Vue,其中集成常用组件,力求方便项目开发。 具体技术实施: 项目采用前后端完全分离模式,并采用严格分层模式,极大的增加聚合度,降低耦合度, 提高代码的健壮性,可维护性。 前后端通过JWT进行身份验证,通过数据接口操作数据,统一使用JSON作为数据格式,并使用默认接口签名算法保证接口的安全性。 功能架构部分详解: 快速开发:此功能为框架的核心,通过选择数据库中的表,就能自动生成对应的实体层、业务逻辑层、控制器、前端页面Vue文件,无需编写代码即可生成基本的CRUD操作。 接口密钥管理:管理接口的密钥,若开启接口签名的规则,则前端需要通过给接口签名才能够正常访问后台接口。 权限管理:使用基本的RBAC权限控制,支持操作权限、接口权限以及数据权限

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧