返回顶部
首页 > 资讯 > 精选 >怎么实现在运行时生成C#的.NET类
  • 439
分享到

怎么实现在运行时生成C#的.NET类

2023-06-03 15:06:45 439人浏览 八月长安
摘要

这篇文章主要介绍“怎么实现在运行时生成C#的.net类”,在日常操作中,相信很多人在怎么实现在运行时生成C#的.NET类问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么实现在运行时生成C#的.NET类”的疑

这篇文章主要介绍“怎么实现在运行时生成C#.net类”,在日常操作中,相信很多人在怎么实现在运行时生成C#的.NET类问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么实现在运行时生成C#的.NET类”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

为什么我需要在运行时生成类?

在运行时生产新类型的需求通常是由于运行时才知道类属性,满足性能要求以及需要在新类型中添加功能。当你尝试这样做的时候,你应该考虑的第一件事是:这是否真的是一个明智的解决方案。在深入思考之前,还有很多其他事情可以尝试,问你自己这样的问题:

  1. 我可以使用普通的类吗

  2. 我可以使用Dictionary、Tuple或者对象数组(Array)?

  3. 我是否可以使用扩展对象

  4. 我确定我不能使用一个普通的类吗?

如果你认为这仍然是必要的,请继续阅读下面的内容。

示例用例

作为一名开发人员,我将大量数据绑定到各种WPF Grids中。大多数时候属性是固定的,我可以使用预定义的类。有时候,我不得不动态的构建网格,并且能够在应用程序运行时更改数据。采取以下显示ID和一些财务数据的类(FTSE和CAC是指数,其属性代表指数价格):

public class PriceHolderViewModel : ViewModelBase{    public long Id { get; set; }    public decimal FTSE100 { get; set; }    public decimal CAC40 { get; set; }}

如果我们仅对其中的属性感兴趣,该类定义的非常棒。但是,如果要使用更多属性扩展此类,则需要在代码中添加它,重新编译并在新版本中进行部署。

相反的,我们可以做的是跟踪对象所需的属性,并在运行时构建类。这将允许我们在需要是不断的添加和删除属性,并使用反射来更新它们的值。

// Keep track of my propertiesvar _properties = new Dictionary<string, Type>(new[]{   new KeyValuePair<string, Type>( "FTSE100", typeof(Decimal) ),   new KeyValuePair<string, Type>( "CAC40", typeof(Decimal) ) });

创建你的类型

下面的示例向您展示了如何在运行时构建新类型。你需要使用 **System.Reflection.Emit**库来构造一个新的动态程序集,您的类将在其中创建,然后是模块和类型。与旧的 ** .NET Framework**框架不同,在旧的版本中,你需要在当前程序的 AppDomain中创建程序集 ,而在 ** .net core**中, AppDomain不再可用。你将看到我使用GUID创建了一个新类型名称,以便于跟踪类型的版本。在以前,你不能创建具有相同名称的两个类型,但是现在似乎不是这样了。

public Type GeneratedType { private set; get; }private void Initialise(){    var newTypeName = Guid.NewGuid().ToString();    var assemblyName = new AssemblyName(newTypeName);    var dynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);    var dynamicModule = dynamicAssembly.DefineDynamicModule("Main");    var dynamicType = dynamicModule.DefineType(newTypeName,            TypeAttributes.Public |            TypeAttributes.Class |            TypeAttributes.AutoClass |            TypeAttributes.AnsiClass |            TypeAttributes.BeforeFieldInit |            TypeAttributes.AutoLayout,            typeof(T));     // This is the type of class to derive from. Use null if there isn't one    dynamicType.DefineDefaultConstructor(MethodAttributes.Public |                                        MethodAttributes.SpecialName |                                        MethodAttributes.RTSpecialName);    foreach (var property in Properties)        AddProperty(dynamicType, property.Key, property.Value);    GeneratedType = dynamicType.CreateType();}

在定义类型时,你可以提供一种类型,从中派生新的类型。如果你的基类具有要包含在新类型中的某些功能或属性,这将非常有用。之前,我曾使用它在运行时扩展 ViewModel和 Serializable类型。

在你创建了 TypeBuilder后,你可以使用下面提供的代码开始添加属性。它创建了支持字段和所需的中间语言,以便通过 Getter和 Setter访问它们。为每个属性完成此操作后,可以使用 CreateType()创建类型的实例。

private static void AddProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType){    var fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);    var propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);        var getMethod = typeBuilder.DefineMethod("get_" + propertyName,        MethodAttributes.Public |        MethodAttributes.SpecialName |        MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);    var getMethodIL = getMethod.GetILGenerator();    getMethodIL.Emit(OpCodes.Ldarg_0);    getMethodIL.Emit(OpCodes.Ldfld, fieldBuilder);    getMethodIL.Emit(OpCodes.Ret);    var setMethod = typeBuilder.DefineMethod("set_" + propertyName,          MethodAttributes.Public |          MethodAttributes.SpecialName |          MethodAttributes.HideBySig,          null, new[] { propertyType });    var setMethodIL = setMethod.GetILGenerator();    Label modifyProperty = setMethodIL.DefineLabel();    Label exitSet = setMethodIL.DefineLabel();    setMethodIL.MarkLabel(modifyProperty);    setMethodIL.Emit(OpCodes.Ldarg_0);    setMethodIL.Emit(OpCodes.Ldarg_1);    setMethodIL.Emit(OpCodes.Stfld, fieldBuilder);    setMethodIL.Emit(OpCodes.Nop);    setMethodIL.MarkLabel(exitSet);    setMethodIL.Emit(OpCodes.Ret);    propertyBuilder.SetGetMethod(getMethod);    propertyBuilder.SetSetMethod(setMethod);}

有了类型后,就很容易通过使用 Activator.CreateInstance()来创建它的实例。但是,你希望能够更改已创建的属性的值,为了做到这一点,你可以再次使用反射来获取 propertyInfos并提取Set方法。一旦有了这些属性,电影它们类设置属性值就相对简单了。

foreach (var property in Properties){    var propertyInfo = GeneratedType.GetProperty(property.Key);    var setMethod = propertyInfo.GetSetMethod();    setMethod.Invoke(objectInstance, new[] { propertyValue });}

现在,您可以在运行时使用自定义属性来创建自己的类型,并具有更新其值的功能,一切就绪。 我发现的唯一障碍是创建一个可以存储新类型实例的列表。 WPF中的DataGrid倾向于只读取List的常规参数类型的属性。 这意味着即使您使用新属性扩展了基类,使用AutoGenerateProperties也只能看到基类中的属性。 解决方案是使用生成的类型显式创建一个新的List。 我在下面提供了如何执行此操作的示例:

var listGenericType = typeof(List<>);var list = listGenericType.MakeGenericType(GeneratedType);var constructor = list.GetConstructor(new Type[] { });var newList = (IList)constructor.Invoke(new object[] { });foreach (var value in values)    newList.Add(value);

到此,关于“怎么实现在运行时生成C#的.NET类”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 怎么实现在运行时生成C#的.NET类

本文链接: https://lsjlt.com/news/234679.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么实现在运行时生成C#的.NET类
    这篇文章主要介绍“怎么实现在运行时生成C#的.NET类”,在日常操作中,相信很多人在怎么实现在运行时生成C#的.NET类问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么实现在运行时生成C#的.NET类”的疑...
    99+
    2023-06-03
  • golang运行时动态生成代码怎么实现
    在Go语言中,可以使用`go/ast`和`go/printer`包来实现动态生成代码。 首先,你需要使用`go/ast`包来创建一棵...
    99+
    2023-10-26
    golang
  • .NET怎么使用System.Timers.Timer类实现程序定时执行
    这篇文章主要讲解了“.NET怎么使用System.Timers.Timer类实现程序定时执行”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“.NET怎么使用System.Timers.Time...
    99+
    2023-07-02
  • C++运行时类型识别与转换实现方法
    目录1.运行时类型转换2.typeid操作符2.1类型转换到中间层次类型2.2void型指针2.3运用带模板的RTTI3.多重继承4.合理使用RTTI5.RTTI的机制和开销6.小结...
    99+
    2024-04-02
  • C#中ObjectARX .NET封装类的访问怎么实现
    这篇文章主要讲解了“C#中ObjectARX .NET封装类的访问怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#中ObjectARX .NET封装类的访问怎么实现”吧!1) 启动...
    99+
    2023-06-18
  • 怎么用C++实现生成括号
    这篇文章主要介绍“怎么用C++实现生成括号”,在日常操作中,相信很多人在怎么用C++实现生成括号问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用C++实现生成括号”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • C++中怎么用Clock类模拟实现闹钟运行
    今天小编给大家分享一下C++中怎么用Clock类模拟实现闹钟运行的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。定义一个时钟类...
    99+
    2023-06-29
  • idea自动生成实体类怎么实现
    实现自动生成实体类的一个方法是使用反射机制和注解来实现。 首先,在需要自动生成实体类的项目中定义一个注解,例如 @Entity 注解...
    99+
    2023-10-24
    idea
  • java动态生成实体类怎么实现
    要实现动态生成实体类,可以使用Java的反射机制。具体步骤如下:1. 创建一个Class对象或者一个Class数组,用于描述实体类的...
    99+
    2023-10-18
    java
  • python怎么实现自动生成C++代码的代码生成器
    这篇文章主要讲解了“python怎么实现自动生成C++代码的代码生成器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python怎么实现自动生成C++代码的代码生成器”吧!遇到的问题工作中遇...
    99+
    2023-07-02
  • 怎么在CSS中实现并排生成多行的dt和dd
    这篇文章主要介绍怎么在CSS中实现并排生成多行的dt和dd,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!   如何实现dt和dd并排   使用<dl><dt&g...
    99+
    2024-04-02
  • C#怎么实现windbg的时间旅行
    本篇内容主要讲解“C#怎么实现windbg的时间旅行”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么实现windbg的时间旅行”吧!一:什么是时间旅行简而言之就是把程序的执行流拍成vlog...
    99+
    2023-06-30
  • 怎么实现在Python退出时强制运行一段代码
    这篇文章主要讲解了“怎么实现在Python退出时强制运行一段代码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现在Python退出时强制运行一段代码”吧!设想这样一个场景,你要给一个项...
    99+
    2023-06-16
  • C++怎么实现随机生成信息功能
    在C++中,可以使用rand()函数来生成随机数。下面是一个简单的示例代码,演示如何生成随机数: #include <iost...
    99+
    2024-03-04
    C++
  • 怎么在python中实现列表生成式
    怎么在python中实现列表生成式?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络...
    99+
    2023-06-14
  • .Net设计模式之建造者、生成器模式怎么实现
    这篇文章主要讲解了“.Net设计模式之建造者、生成器模式怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“.Net设计模式之建造者、生成器模式怎么实现”吧!一、动机(Motivation...
    99+
    2023-06-30
  • 怎么用vbs实现定时运行web文件
    本篇内容主要讲解“怎么用vbs实现定时运行web文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用vbs实现定时运行web文件”吧!在一定的时候,要定时的运行某个ASP文件去执行一个任务,...
    99+
    2023-06-08
  • .NET 实现启动时重定向程序运行路径及 Windows 服务运行模式部署的方法
    日常工作中有时候会遇到需要将程序直接在服务器上运行,而不依赖于 IIS 托管的情况,直接运行有两种方式,一种是部署为 服务模式,另一种则是 直接启动 .NET 发布之后的 exe 文...
    99+
    2024-04-02
  • C++实现即时通信的示例代码(直接运行)
    目录题目软件:VS服务器端客户端题目 由于本学期上了网络编程课程,老师要求写使用Socke实现网络编程。于是参考 C++多线程实现即时通信软件 写出了简单版本的没有界面的即时通信软件...
    99+
    2024-04-02
  • C++实现统计代码运行时间的示例详解
    目录纯标准库实现类似C#的实现总结本来想自己写的,一看github上面都有就不再重复造轮子了。github上的项目如下: StopWatch 纯标准库实现:使用std::chrono...
    99+
    2023-05-19
    C++统计代码运行时间 C++ 代码运行时间 C++统计时间
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作