为了账号安全,请及时绑定邮箱和手机立即绑定

C# 隐藏类型到相同类型的 IEnumerable 中?

C# 隐藏类型到相同类型的 IEnumerable 中?

C#
精慕HU 2021-11-14 16:58:23
我有一些方法可以对数据库执行任意 SQL 并将该数据集合序列化为具体类型的列表。然后将该数据序列化为 JSON 并存储在表格的单元格中。稍后,我需要返回并将该数据反序列化回其原始集合,以便可以使用它。我在弄清楚如何获取Type对象并创建该类型的集合以对其进行反序列化时遇到了一些问题。这是我的代码的运行方式:public async Task ExecuteWidget(Guid runGuid, string widgetName, Type type, string sql,    IEnumerable<SqlParameter> parameters){    var report = operationsContext.ReportRuns.FirstOrDefault(n => n.RunGuid == runGuid);    CheckReportStatus(report);    var param = parameters.ToList();    var result = edwContext.Database.SqlQuery(type, sql, param.ToArray<object>());    var query = result.GetQuery(param);    var data = await result.ToListAsync();    var widgetData = new ReportRunWidgetData()    {        ReportRunId = report?.ReportRunId ?? -1, // This should never be null.        WidgetName = widgetName,        WidgetData = new JavaScriptSerializer().Serialize(data),        Query = query    };    operationsContext.ReportRunWidgetDatas.Add(widgetData);    await operationsContext.SaveChangesAsync();}我的获取逻辑如下所示:public object FetchWidgetData(Guid runGuid, string widgetName, Type dataType){    var data = operationsContext.ReportRuns        .Include("ReportRunWidgetDatas")        .FirstOrDefault(n => n.RunGuid == runGuid)?        .ReportRunWidgetDatas.FirstOrDefault(n => n.WidgetName == widgetName)?        .WidgetData;    if (data == null) return null;    var deserialized = new JavaScriptSerializer().Deserialize(data, dataType);    return deserialized;}现在,当ExecuteWidget调用该方法时,该type参数由小部件的 DTO 数据类型填充。例如HeadlineWidgetDTO。但是,执行命令将数据作为List<HeadlineWidgetDTO>. 当我的FetchWidgetData方法被调用时,dataType提供的仍然是HeadlineWidgetDTO,但它实际上需要是IEnumerable<HeadlineWidgetDTO>正确反序列化的类型。仅给定单个数据行的类型,如何创建一个Type对象而不是该类型的集合?
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

基本上,如果您有一个类型 object Type theType,则需要执行以下操作:


 var listType = typeof(List<>);

 var typeParams = new [] {theType};

 var listOfTType = listType.MakeGenericType(typeParams);

 var newListOfT = Activator.CreateInstance(listOfTType);

此时,您有一个 type 变量object,但它引用了一个 type 对象List<WhateverYourTypeIs>。说,theTypeis typeof(int),那么你将有一个 的对象List<int>。不过,将它转换为可用的东西是另一个问题。如果你想在这个列表中添加一些东西,我怀疑最好的方法是MethodInfo为Add方法和Invoke它获取一个。


如果类型具有默认构造函数并且创建起来不太昂贵,我想到了另一种方法来做到这一点。这是一个示例(创建一个List<int>- 但这只是我编码的方式):


  var type = typeof(int);

  var dummy = Activator.CreateInstance(type);

  var listOfType = new[] {dummy}.ToList();

完成后,listOfType变量的类型为 aList<object>但指的是 a List<int>。它主要是可行的 - 例如,您可以调用Add(object someObj)它。你不会得到编译类型参数类型检查,但你可以使用它。


查看完整回答
反对 回复 2021-11-14
  • 1 回答
  • 0 关注
  • 162 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信