C#动态调用泛型类、泛型方法

在制作一个批量序列化工具时遇到了如下问题,在此记录一下,仅供参考。

      主程序加载另一个程序集,将其中的所有类取出,然后对这些类分别调用泛型类或泛型方法。控制台程序解决方案如下:

  • Main工程:提供Worker类进行数据操作,XMLTool<T>泛型类将数据集序列化为.xml文档,RootCollection<T>类封装数据集
    • Worker类

           提供成员方法void DoWork<T>()、List<T> GetList<T>()、静态成员方法StaticDoWork<T>(),代码如下:

    复制代码
     1 public class Worker
    2 {
    3 public Worker()
    4 {
    5 }
    6
    7 public void DoWork<T>()
    8 {
    9 Type t = typeof(T);
    10 Console.WriteLine("Get Class: {0}", t.Name);
    11 PropertyInfo[] properties = t.GetProperties();
    12 foreach (PropertyInfo property in properties)
    13 {
    14 Console.WriteLine("\tproperty.Name: " + property.Name + "\tproperty.MemberType: " + property.PropertyType);
    15 }
    16 }
    17
    18 public static void StaticDoWork<T>()
    19 {
    20 Type t = typeof(T);
    21 Console.WriteLine("Get Class: {0}", t.Name);
    22 PropertyInfo[] properties = t.GetProperties();
    23 foreach (PropertyInfo property in properties)
    24 {
    25 Console.WriteLine("\tproperty.Name: " + property.Name + "\tproperty.MemberType: " + property.PropertyType);
    26 }
    27 }
    28
    29 public List<T> GetList<T>()
    30 {
    31 Console.WriteLine("Generate List for [{0}]", typeof(T).Name);
    32 return new List<T>()
    33 {
    34 Activator.CreateInstance<T>(),
    35 Activator.CreateInstance<T>()
    36 };
    37 }
    38 }
    复制代码

     

    • XMLTool<T>类
      复制代码
       1publicclass XMLTool<T>
      2 {
      3publicstaticvoid XmlSerialize_Save(List<T> needSerializedList, string xmlDirPath, string xmlFileName)
      4 {
      5 RootCollection<T> collection = new RootCollection<T>();
      6 collection.ItemList = needSerializedList;
      7if (!Directory.Exists(xmlDirPath))
      8 Directory.CreateDirectory(xmlDirPath);
      9using (System.IO.FileStream stream = new System.IO.FileStream(xmlFileName, System.IO.FileMode.Create))
      10 {
      11 System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(collection.GetType());
      12 serializer.Serialize(stream, collection);
      13 }
      14 }
      15 }
      复制代码
    • RootCollection<T>类:
      复制代码
       1     [Serializable]
      2 public class RootCollection<T>
      3 {
      4 public RootCollection()
      5 {
      6 itemList = new List<T>();
      7 }
      8
      9 private List<T> itemList;
      10
      11 public List<T> ItemList
      12 {
      13 get { return itemList; }
      14 set { itemList = value; }
      15 }
      16 }
      复制代码
  • MockClassLib工程:提供BaseEntity、Apple、Cat和Person类
    • BaseEntity类:抽象类,负责初始化类成员
      复制代码
       1     public abstract class BaseEntity
      2 {
      3 public BaseEntity()
      4 {
      5 InitiaWithNull();
      6 }
      7
      8 private void InitiaWithNull()
      9 {
      10 Type type = this.GetType();
      11 PropertyInfo[] properties = type.GetProperties();
      12 string[] PropNames = new string[properties.Length];
      13 Dictionary<string, PropertyInfo> PropNameToInfo = new Dictionary<string, PropertyInfo>();
      14 for (int i = 0; i < properties.Length; i++)
      15 {
      16 PropNames[i] = properties[i].Name;
      17 PropNameToInfo.Add(PropNames[i], properties[i]);
      18 }
      19
      20 foreach (string propname in PropNames)
      21 {
      22 string proptype = PropNameToInfo[propname].PropertyType.Name;
      23
      24 object value = null;
      25 if (NullValue.Keys.Contains(proptype))
      26 value = NullValue[proptype];
      27
      28 type.GetProperty(propname).SetValue(this, value, null);
      29 }
      30 }
      31
      32 private static readonly Dictionary<string, object> NullValue = new Dictionary<string, object>()
      33 {
      34 { "String", String.Empty },
      35 { "DateTime", DateTime.MinValue},
      36 { "Decimal", Decimal.MinValue}
      37 };
      38 }
      复制代码
    • Apple、Cat和Person类:测试类,继承于BaseEntity
      复制代码
       1     public class Apple : BaseEntity
      2 {
      3 public string Color { get; set; }
      4 }
      5
      6 public class Cat : BaseEntity
      7 {
      8 public string Type { get; set; }
      9 }
      10
      11 public class Person : BaseEntity
      12 {
      13 public int ID { get; set; }
      14 public string Name { get; set; }
      15 }
      复制代码

 

      Main工程的Program的Main方法中,一般情况下,调用Worker的泛型方法来处理测试类的话,可以写为:

      Worker worker = new Worker();

      worker.DoWork<Apple>();

      worker.DoWork<Cat>();

      worker.DoWork<Person>();

      但是,如果MockClassLib中需要处理的类型非常多时,这样显示调用必然是不灵活的,应当怎样向泛型方法DoWork<T>()的尖括号中动态传入类型呢?

      考虑代码:

复制代码
            //Load assembly
Assembly mockAssembly = Assembly.LoadFrom("MockClassLibrary.dll");
Type[] typeArray = mockAssembly.GetTypes();

//Create instance of Worker
Worker worker = new Worker();
foreach(Type curType in typeArray)
{
worker.DoWork<curType>(); //Error
}
复制代码

      可以看到,Type类型的实例是无法直接传入泛型方法的尖括号中的,T要求显式指明类型名。

      下面通过反射方式来获取泛型方法,并创建特定类型的泛型方法。

  • 对于非静态方法:public void DoWork<T>()

          对于非静态方法,调用MethodInfo.Invoke(object, object[])时,第一个参数需要指明泛型方法的所有者(即这里创建的worker对象),第二个参数为泛

          型方法的参数列表,DoWork<T>()没有输入参数,所以设为null

复制代码
//Create an instance of Worker
Worker worker = new Worker();

//Get type of Worker
Type workerType = typeof(Worker);

//Get Generic Method
MethodInfo doWorkMethod = workerType.GetMethod("DoWork");

//Invoke DoWork<T> with different Type
foreach (Type curType in typeArray)
{
if (curType.IsClass && !curType.IsAbstract)//Filter BaseEntity
{
MethodInfo curMethod = doWorkMethod.MakeGenericMethod(curType);
curMethod.Invoke(worker, null);//Member method,use instance
}
}
复制代码
  • 对于静态方法:public static void StaticDoWork<T>()

          不同于非静态方法,这里直接反射的类静态方法,所以Invoke()的第一个参数设为null

复制代码
//Get type of Worker
Worker worker = new Worker();

//Get Generic Method
MethodInfo staticDoWorkMethod = workerType.GetMethod("StaticDoWork");

//Invoke StaticDoWork<T>
foreach (Type curType in typeArray)
{
if (curType.IsClass && !curType.IsAbstract)
{
MethodInfo curMethod = staticDoWorkMethod.MakeGenericMethod(curType);
curMethod.Invoke(null, null);//Static method
}
}
复制代码
  • 对于有返回值的非静态方法:public List<T> GetList()

          如同动态调用DoWork<T>()方法一样,只是在处理返回值时,可以使用下面的方法

1 IList tempList = (IList)curMethod.Invoke(worker, null);
2 //Or
3 IEnumerable tempList = (IEnumerable)curMethod.Invoke(worker, null);
  • 对于泛型类:XMLTool<T>

          下面要使用泛型类XMLTool<T>的静态方法public static void XmlSerialize_Save(List<T> list, string dirPath, string fileName)方法。

          首先应通过反射构造出指定类型的泛型类XMLTool<T>,再反射出其中的XmlSerialize_Save方法并使用。

复制代码
 1 //Use Generic Class
2 Type xmlToolType = typeof(XMLTool<>).MakeGenericType(curType);
3
4 //Get method
5 MethodInfo saveMethod = xmlToolType.GetMethod("XmlSerialize_Save");
6
7 //Invoke
8 saveMethod.Invoke
9 (
10 null, //Static method
11 new object[] { resultList, @"c:\", @"c:\Test_" + curType.Name + ".xml" }

12 );
复制代码

 

       Program-->Main()方法的全部代码:

复制代码
 1 namespace RetrieveUnknownClass
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 //Load assembly
8 Assembly mockAssembly = Assembly.LoadFrom("MockClassLibrary.dll");
9 Type[] typeArray = mockAssembly.GetTypes();
10
11 //Create instance of Worker
12 Type workerType = typeof(Worker);
13 Worker worker = new Worker();
14
15 #region Member method
16
17 Console.WriteLine(">>>>>>>>>Use Generic Method:");
18 MethodInfo doWorkMethod = workerType.GetMethod("DoWork");
19
20 //Invoke DoWork<T>
21 foreach (Type curType in typeArray)
22 {
23 if (curType.IsClass && !curType.IsAbstract)
24 {
25 MethodInfo curMethod = doWorkMethod.MakeGenericMethod(curType);
26 curMethod.Invoke(worker, null);//Member method,use instance
27 }
28 }
29
30 #endregion
31
32 #region Static method
33
34 Console.WriteLine("\r\n>>>>>>>>>Use Static Generic Method:");
35 MethodInfo staticDoWorkMethod = workerType.GetMethod("StaticDoWork");
36
37 //Invoke StaticDoWork<T>
38 foreach (Type curType in typeArray)
39 {
40 if (curType.IsClass && !curType.IsAbstract)
41 {
42 MethodInfo curMethod = staticDoWorkMethod.MakeGenericMethod(curType);
43 curMethod.Invoke(null, null);//Static method
44 }
45 }
46
47 #endregion
48
49 #region Get A List & Serialize It to Xml File With Generic
50
51 Console.WriteLine("\r\n>>>>>>>>>Get List By Generic Method:");
52 MethodInfo getListMethod = workerType.GetMethod("GetList");
53
54 foreach (Type curType in typeArray)
55 {
56 if (curType.IsClass && !curType.IsAbstract)
57 {
58 MethodInfo curMethod = getListMethod.MakeGenericMethod(curType);
59 //Generate List
60 IList resultList = (IList)curMethod.Invoke(worker, null);
61 //Show List
62 ShowList(resultList);
63 //Use Generic Class
64 Type xmlToolType = typeof(XMLTool<>).MakeGenericType(curType);
65 MethodInfo saveMethod = xmlToolType.GetMethod("XmlSerialize_Save");
66
67 saveMethod.Invoke
68 (
69 null, //Static method
70 new object[] { resultList, @"c:\", @"c:\Test_" + curType.Name + ".xml" }
71 );
72 }
73 }
74
75 Console.WriteLine("Serialization Completed...\r\n");
76 #endregion
77 }
78
79 public static void ShowList(IList list)
80 {
81 Console.WriteLine("Type of list: {0}\r\nCount of current list: {1}\r\nType of item in list: {2}\r\n",
82 list.GetType(),
83 list.Count,
84 list[0].GetType());
85 }
86 }
87 }
复制代码

转载于:https://www.cnblogs.com/smiler/p/10177356.html

基于ESP32和OV5640的目标检测系统 本文详细介绍了基于ESP32-S3和OV5640摄像头构建目标检测系统的完整方案。系统采用YOLOv8-Nano轻量级模型,通过INT8量化实现边缘部署,在UXGA分辨率下达到25fps帧率。文章从硬件选型、图像采集优化、模型量化部署、实时推理流水线构建等维度展开,重点解决了内存管理、电源稳定性和异常处理等嵌入式系统关键问题。该方案在资源受限条件下实现了150ms以内的端到端延迟,为物联网视觉应用提供了低成本、低功耗的解决方案,适用于智能家居、工业检测等多个场景。 阅读详情

相关推荐

【论文阅读|小目标分割算法ASF-YOLO】

论文题目:ASF-YOLO: A novel YOLO model with attentional scale sequence fusion for cell instance segmentation 论文链接: https://arxiv.org/abs/2312.06458 代码链接:https://github.com/mkang315/ASF-YOLO 摘要(Abstract) 作者提出了一种新颖的基于 "You Only Look Once"(YOLO)的注意力尺度序列融合框架(ASF-YO

dally2的博客 8118

C# 动态调用泛型方法

static void Main(string[] args) { #region 具体类型可传递。 Personal specifiedPersonal = new Personal(); Employee<Personal> employee = new Employee&lt...

weixin_30640769的博客 692

Geant4 案例分析(一): B1

本文是对Geant4 B1的案例分析,其中特定的功能不做介绍,而注重于各个文件的主要功能,以及它们组织的方式。

m0_51809467的博客 1579

C# 通过反射来动态创建泛型类型

c# 反射 泛型

keebai的专栏 1152

Cadence OrCAD: 层次化设计 Hierarchical Design

详细介绍OrCAD的原理图层次化设计方法。

Fantasy237的博客 1万+

别再纠结高边低边了!用TI BQ76952设计两轮车BMS,手把手教你选对架构(附电路图)

本文深度解析基于TI BQ76952芯片的电动两轮车BMS设计策略,涵盖高边/低边驱动选择、四种基础架构的电流路径分析及选型决策矩阵。通过实战案例分享,帮助工程师优化BMS架构,提升系统可靠性和成本效益,特别适合电摩和共享单车应用场景。

weixin_42665255的博客 513

C# 使用反射动态调用泛型方法

通常我们能用到泛型方法时,如 fun<T>() 如果泛型的T类型过多,如果使用swich会产生大量的冗余代码,通过反射动态的生成代码,可以减少大量的代码量。

Tas的博客 1万+

【论文复现】——基于欧式聚类的车载点云道路提取

针对车载激光点云道路信息提取的问题,提出了一种基于欧式聚类的道路提取方法。首先通过统计滤波去除噪点以免对后续处理结果产生影响,然后用坡度滤波去除路坎点,使道路边界与人行道、绿化带等与路坎相连的地物形成10~25 cm的高程阶跃,最后用欧式聚类将路面点云与其他地物点云聚类为一簇或多簇并保留道路簇,从而实现道路点云的精确提取。

点云侠的博客 1134

C# 泛型概念及用法详解

泛型(generic)是C# 2.0推出的新语法,它是专门为处理多段代码在不同的数据类型上执行相同的指令的情况而设计的。比如说编程时,碰到功能非常相似的模块,只是它们所处理的数据类型不同,然而我们却需要写不同的方法来实现它,很明显,这加大了我们的工作量,也很乏味。有没有什么办法能够解决这个问题呢?它就是泛型了,可以让多个类型共享一组代码。通过压栈例子可以更清楚的了解泛型{int[] arr;//将int类型的值压栈//将float类型的值压栈。

u011555996的博客 1万+

YOLOv11改进 | 引入SFSConv空间频率选择卷积(含SFSC3k2二次创新),空间频率特征协同作用,检测性能全面提升

本文提出在YOLOv11中引入SFSConv空间频率选择卷积模块,通过显式分离和动态融合空间域与频率域特征,解决传统卷积对多尺度目标检测的局限性。SFSConv包含空间频率分离、动态权重融合和协同特征重建三个核心机制,并进一步创新提出SFSC3k2结构,通过双路频率分支增强特征协同作用。该改进显著提升了YOLOv11在遥感、医学等多尺度复杂场景下的检测性能,实验显示在微小目标检测任务中mAP提升5%-10%。代码实现展示了SFSConv模块的核心逻辑及其在PyTorch中的高效实现。

走向CTO的路上... 767

YOLOv12优化:原创自研 | 带有注意力机制的隐藏状态混合器的状态空间(HSM-SSD),实现暴力涨点 | CVPR2025 EfficientViM

可以将 带有注意力机制的隐藏状态混合器的状态空间(HSM-SSD)中的注意力机制换成专栏其他注意力机制 ,那么你就能实现独一无二的原创。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 662

C#根据名称字符串创建对象(泛型类与泛型方法)

根据类名字符串来实例化泛型类与其中的泛型方法

syzcyyx的博客 2210

Y-Branch and a closed y-branch loop

双臂后面的区域,我们将它的双臂使用一个波导进行了连接,使得它本身形成了一个闭合回路,因此,该结构被称作。它们均是用来对经过它们的光束能量进行分割的一种器件。首先,我们知道一点,在光波导层面,今天给大家介绍一下,什么是。

u011699626的博客 627

C# 反射泛型

C# 反射泛型 摘自:http://www.itwis.com/html/net/c/20110411/10175.html C#泛型反射和普通反射的区别,泛型反射和普通反射的区别就是泛型参数的处理上   先看一个简单的例子。   class Class1 {   public void Test(T t)   {     Console.WriteLine(t);

u012329294的专栏 1346

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

如何通过C#.NET中的反射机制来创建C#.NET泛型类的实例,并调用其方法??

<br />如何通过C#.NET中的反射机制来创建C#.NET泛型类的实例,并调用其方法??悬赏分:40|解决时间:2008-11-25 16:37|提问者:rjgaoyuan请举一个简单易懂的小例子来说明… 反射普通类和反射泛型类是不同的… public abstract class BusinessManager { /// <summary> /// 添加一个新实体 /// </summary> /// <param nam

rise51的专栏 907

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

采用异步来实现重新连接服务器或者重新启动服务 C#中类的属性的获取 SignalR2简易数据看板演示 C#动态调用泛型类、泛型方法 asp .net core Get raw request....

采用异步来实现重新连接服务器或者重新启动服务 开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端! #region 检测断线并重连OPC服务 可以强制启动OPC服务程序/// <summary>/// 提供外部使用/// 重新连接事件/// </summary>public eve...

562

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

泛型和反射

一、概念 泛型允许程序员在代码中将变量或参数的类型,先用[类型占位符]来代替,等到允许的时候再根据传入的[类]来代替 泛型是指带类型参数的类,而不是参数本身。 可以定义多个参数  public class Person 实例化一个引用参数类型的泛型,它的内存分配的大小是一样的

LengSeXiZuo的专栏 570

C#反射用法合集Reflection

本文只介绍使用方式,不介绍理论基础。理论和详细教程请直接看官网 测试类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Console; namespace SqlDB { public class ReflectionTest { private Re

csdn2990的博客 560

使用反射动态加载dll

使用反射动态加载dll //1.动态读取Dll Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"\EVEDAS.UPDLL.dll"); //2.获取某一个具体的类型:参数需要是类的全名称; Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); //3.创建对象 object? oInstance = Activator.Cre

qq_27577403的博客 1430

【泛型】

C#泛型获取传入的动态类型参数的属性值的问题 dynamic tt = SortObj.GetType().GetProperty(Key).GetValue(SortObj, null); 对C#泛型实例化对像,在使用泛型的类后面加入一个 where T : new(),代码如下: public class B<T> where T : new() {   pu...

weixin_30374009的博客 78

反射调用泛型

class GenClass<T>{ public void Note(T t) { Console.WriteLine(t); }}调用 var ass = Assembly.Load("TextCord");//反射调用泛型var type_q = ass.GetType("TextCord.GenClass`1");var typeMa...

weixin_38170853的博客 379

使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型...

C#反射中的MakeGenericType函数可以用来指定泛型方法和泛型类的具体类型,方法如下面代码所示这里就不多讲了,详情看下面代码一切就清楚了: using System; using System.Reflection; namespace RFTest { //类ReflectionTest中定义了一个泛型函数DisplayType和泛型类MyGener...

davy57345的博客 353

C# 高级编程个人笔记搬运 六(泛型——方法)

接着上一篇幅,因为太长了不方便看。正好泛型方法本来也是一个常用到的技术,就单独拎出来讲好了。 泛型方法: 不仅接口、类和结构可以是泛型的,方法也可以是泛型的。在泛型方法中,泛型类型用方法声明来定义。泛型方法可以在泛型类型中定义。Swap<T>()方法把T定义为泛型类型,该类型用于两个参数金额一个变量temp: void Swap<T>(ref T x, ref T y) { T temp; temp = x; x = yl y = temp;

TOTOLOG的博客 302
上一篇: Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二)
下一篇: git clone 指定分支
dddp75921
博客等级 码龄12年 9粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值