在我公司的应用程序中,有一个查看器会接收消息并从中创建XML文档,以便为客户提供良好的显示。每条消息都有自己的类,到目前为止必须单独编写,如下面的例子中所示。类名在" m_msgTypeVersion"中给出,所以我认为应该可以使用反射来概括这个switch语句中的情况,这样当新的消息类型不是必须更新时添加到应用程序中。
但是,我在这方面遇到了一些麻烦。我不知道如何投射到特定类型。我使用的是.NET 3.5,因此动态关键字不在那里。但我需要将实例强制转换为特定的类而不是Object。
如何使用Serializer?它说它需要一个T.但我的类型并不适用于此。它给出了语法错误。
switch (m_msgTypeVersion)
{
default:
throw new NotImplementedException("Message type " + m_msgTypeVersion + " conversion to XmlElement not implemented!");
case "UTILMD_D11AUN51":
UTILMD_D11AUN51 utilmd51 = new UTILMD_D11AUN51();
Serializer<UTILMD_D11AUN51> serUtilmd51 = new Serializer<UTILMD_D11AUN51>();
if (serUtilmd51.Deserialize(m_ediMsg, out utilmd51, out ex))
xml = new XmlDocument().ReadNode(serUtilmd51.Serialize(utilmd51, "").Root.CreateReader()) as XmlElement;
break;
case "UTILMD_D11AUN51a":
UTILMD_D11AUN51a utilmd51a = new UTILMD_D11AUN51a();
Serializer<UTILMD_D11AUN51a> serUtilmd51a = new Serializer<UTILMD_D11AUN51a>();
if (serUtilmd51a.Deserialize(m_ediMsg, out utilmd51a, out ex))
xml = new XmlDocument().ReadNode(serUtilmd51a.Serialize(utilmd51a, "").Root.CreateReader()) as XmlElement;
break;
case ...
}
return xml;
我的尝试......
Type type = Type.GetType("m_msgTypeVersion");
Object myObject = Activator.CreateInstance(type); // need not object, but cast to specific type
Serializer<type> serUtilmd51 = new Serializer<type>(); // does not work with "type"
答案 0 :(得分:2)
基本上,你在这里有三个选择(没有动态);做一切反思,做硬核元编程,或使用单个反射黑客跳转到泛型方法。后者可能是你最好的选择,所以:
public static void EvilHack<T>(...args...)
{
T myObject = Activator.CreateInstance<T>();
Serializer<T> serUtilmd51 = new Serializer<T>();
// etc
}
Type type = Type.GetType("m_msgTypeVersion");
typeof(YourEnclosingType).GetMethod("EvilHack").MakeGenericMethod(type)
.Invoke(null, args);
请注意,您可以添加返回类型等,并从.Invoke
捕获返回值。在这种情况下,null
调用中的前导.Invoke
是实例 - null
,因为它是static
方法;如果使方法非静态,则将其替换为目标实例。如果您将方法设为非public
,则需要在BindingFlags
调用中指定GetMethod
。
完全正常的例子:
using System;
class YourEnclosingType
{
static void Main()
{
Type type = Type.GetType("m_msgTypeVersion");
object[] args = null; // no args
typeof(YourEnclosingType).GetMethod("EvilHack").MakeGenericMethod(type)
.Invoke(null, args);
}
public static void EvilHack<T>()
{
T myObject = Activator.CreateInstance<T>();
Serializer<T> serUtilmd51 = new Serializer<T>();
serUtilmd51.DoIt(myObject);
}
}
class m_msgTypeVersion // worst. name. ever
{ }
class Serializer<T>
{
public void DoIt(T obj)
{
Console.WriteLine("I'm serializing " + obj);
}
}