C#将动态字符串转换为现有类

C#将动态字符串转换为现有类,c#,string,class,dynamic,C#,String,Class,Dynamic,在windows应用程序中,使用C#,我有一个报告模块,它依赖于类来填充报告。然而,将会有很多报告,我不想为每个报告编写代码 流程如下所示: 在报表编辑器中,报表将被指定一个类(即“应用程序”)作为字符串。 当用户选择要运行的报表时,代码将从SQL查询中获取数据。 代码将获取数据并找出将数据放入哪个类。 然后,报表将获取该类并使用该类中的数据填充报表 这是我的dilemna,如何使代码动态化,以便代码将指定的类转换为适当的类对象 记住的例子: gVar = Report; (gVar.Repor

在windows应用程序中,使用C#,我有一个报告模块,它依赖于类来填充报告。然而,将会有很多报告,我不想为每个报告编写代码

流程如下所示: 在报表编辑器中,报表将被指定一个类(即“应用程序”)作为字符串。 当用户选择要运行的报表时,代码将从SQL查询中获取数据。 代码将获取数据并找出将数据放入哪个类。 然后,报表将获取该类并使用该类中的数据填充报表

这是我的dilemna,如何使代码动态化,以便代码将指定的类转换为适当的类对象

记住的例子:

gVar = Report;
(gVar.ReportClass)oClass = new gVar.ReportClass;
使用(特别是采用
字符串
参数的重载之一(例如)为适当的类加载
类型
的实例,然后在
类型
的实例上使用或实例化实例

比如

Type type = Type.GetType(assemblyQualifiedName);
object instance = Activator.CreateInstance(type);
请注意,除非类型在mscorlib或当前正在执行的程序集中,否则必须传递

此外,
Activator.CreateInstance
假定存在默认构造函数。如果没有默认构造函数,或者需要将某些参数传递给构造函数,则必须使用允许指定构造函数参数的of
Activator.CreateInstance
,或者使用
Type.GetConstructor
加载适当的构造函数。

使用隐式运算符即可:

这听起来很适合您的需要,因为它允许您执行以下操作:

Orange orange = new Orange();
Apple apple = (Apple)orange;
myBaseReport report = (myBaseReport)System.Activator.CreateInstance("MyAssemblyName", myClassStringWithFullNameSpace).Unwrap();
或:

隐式运算符将该apple JSON序列化字符串反序列化为常规apple类型对象

我不知道这是否是你想要的,如果这是一个C#功能,我希望没有人会投票反对

编辑:我误解了这个问题。多亏了评论家们,即使他们否决了我的答案,因为我错了

编辑2:

以others Activator/Reflection方法(这似乎是当前问题作者的正确方法)为例,阅读他关于“如何填充获取的报表实例的属性”的另一个问题,我想提出一些解决方案

您可以定义一些属性,如“ReportPropertyAttribute”,但不包含属性、默认构造函数,并使用反射检查标记为建议属性的属性

或者您可以定义一些配置文件或配置节(常规的.NET配置API),以便定义“已知报告类型”和“哪些属性是某些报告类型的参数”


我希望这符合你的需要

有点不清楚你到底想要什么。但是,根据我读到的内容,您有一个包含类型名的字符串,并且希望基于该字符串实例化一个类?您可以使用反射来完成此操作

Type type = Type.GetType(strTypeName);
object oClass = Activator.CreateInstance(type);

您可以使用反射来完成此操作。如果您为它们提供一些类似的基类或接口,您可以执行以下操作:

Orange orange = new Orange();
Apple apple = (Apple)orange;
myBaseReport report = (myBaseReport)System.Activator.CreateInstance("MyAssemblyName", myClassStringWithFullNameSpace).Unwrap();

这将进入名为的程序集并直接加载类。类字符串是所讨论类型的全名,因此类似于
MyGlobalNamespace.MyCustomNameSpace.MySpecificType
。这将允许您创建特定类型的报表,并将其放入基类类型或接口类型。

谢谢Anthony我放弃我不知道如何正确地表达我的问题,这样就不会弹出问题。马特。我只是添加了副本,以便这些副本可以链接。我会检查这个问题。它应该回答你的问题(如果我理解正确的话)。这是假设他已经知道了类型。我的问题是,类型可能会有所不同,他在运行时之前不会知道实际的类型。这不适用。好吧,他提供的信息越少,我试着认为他处于另一种情况,因为他说“我不想重复将A转换为B的代码”。我确实说过报告将被分配一个类(即“应用程序”)作为字符串,“我如何使代码动态,以便代码将分配的类转换为适当的类对象?”?“好的,现在我已经仔细检查了你的文本,我理解了这个问题。我相信其他人建议的反射/激活器方法是正确的方法,或者,您可以使用控制反转。我将使用激活器,但是我不清楚在我使用数据填充类对象之后该怎么做,因为它将在运行时完成不幸的是,没有两个报表类是相同的,因此,没有创建基类或接口。@mattgcon-那么在执行此类实例化时,最好将其作为对象键入。而您传递给的任何方法都需要接受object。@JoelEtherton:我投了赞成票,因为您提到了带有完整名称空间的类名,这说明了如何使用它。不过,当我从字符串中恢复类时,我突然想到了一个问题,我猜没有办法将数据动态地放入类中相应的属性中。(即reportclass.clientname=dt[“clientname”].ToString()),如果您知道您的对象将具有这样的属性(假设因为动态实例化的所有对象都派生自公共基类或公共接口,所以可以强制转换到该基类或接口,然后通过该基类或接口访问属性)。因此,假设您的所有对象都派生自名为
Report
的类,并且
Report
具有名为
ClientName
的属性。然后您可以说
Report r=(Report)Activator.CreateInstance(type);r.ClientName=dt[“ClientName”].ToString();
。或者,您可以使用反射来