因此,我有一种方法可以通过使用泛型实现我所需要的,并从答案中获得帮助-
Dynamically create a class in C#
第一件事是转换
SomeEventName
使用泛型,这样我就可以将其用作基类。这个
GetType()
这样我就可以区分可以创建的每种类型。这给了我:
public class EventBase
{
public string HardwareId { get;set; }
public DateTime MessageGeneratedTime { get; set; }
public DateTime MessageReceivedTime { get; set; }
public DateTime MessageAdaptedTime { get; set; }
public override string ToString()
{
return string.Format("{0} event - HardwareId: {1}, CreateTime: {2}, MessageReceivedTime: {3}", GetType(), HardwareId, MessageGeneratedTime, MessageReceivedTime);
}
public T Default<T>(string dardwareId, DateTime createTime, DateTime receiveTime) where T : TestBase, new()
{
var instance = new T
{
HardwareId = hardwareId,
MessageGeneratedTime = createTime,
MessageReceivedTime = receiveTime,
MessageAdaptedTime = DateTime.UtcNow
};
return instance;
}
}
接下来我需要实例化每个类型。我一开始只有一种类型,但我可以很容易地扩展我所拥有的内容来创建其他类型。因此,在上述答案的帮助下,我最终得出:
var myType = CompileResultType(properties);
var myObject = Activator.CreateInstance(myType);
虽然我不会包括答案中的所有代码,但关键是:
private static TypeBuilder GetTypeBuilder()
{
var typeSignature = "SomeEventName";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("TypeOfTest");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature
, TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
typeof(TestBase),
null);
return tb;
}
在该代码中,我创建了
某些事件名称
给它我的基类,
EventBase
.
曾经我有一次
type
和
object
,然后我可以传递一些参数并调用
Default
方法,同时使其成为泛型。
var arguements = new object[] { "QWERTY", DateTime.UtcNow, DateTime.UtcNow };
var @event = myObject.GetType().GetMethod("Default").MakeGenericMethod(myObject.GetType()).Invoke(myObject, arguements);
因为这是在控制台应用程序中,所以我可以调用
ToString
override,基于上述代码中的参数,输出:
SomeEventName事件-设备:QWERTY,创建时间:05/10/2015 15:18:25,
消息接收时间:2015年10月5日15:18:25
另一个要求是我可以创建属性,在上面的代码中,您可以看到我调用
CompileResultType
传递参数列表。所以我所做的就是:
var properties = new Dictionary<string, string>();
properties.Add("Field1", "System.String");
properties.Add("Field2", "System.Int32");
然后,我当然可以通过以下方式设置它们的值:
myObject.GetType().GetProperty("Field1").SetValue(myObject, "Hello world");
myObject.GetType().GetProperty("Field2").SetValue(myObject, 987);
然后使用以下命令将它们输出到控制台窗口:
Console.WriteLine("Field1: {0}", myObject.GetType().GetProperty("Field1").GetValue(myObject));
Console.WriteLine("Field2: {0}", myObject.GetType().GetProperty("Field2").GetValue(myObject));
虽然它可能不是最好的解决方案,而且它确实有它的缺点,比如一切都变成了字符串,但它做了所需的事情。如上所述,这仅适用于一种类型,但可以通过传递
signature
作为字符串
编译结果类型
然后将其传递给
GetTypeBuilder
.