看到我有这样的情况......
object myRoledata = List<Roles>() --> (some list or Ienumerable type)
现在我有一个从List<T>
创建XML对象的通用方法 -
像这样......
public string GetXML<T>(object listdata)
{
List<T> objLists = (List<T>)Convert.ChangeType(listData, typeof(List<T>));
foreach(var obj in listdata)
{
//logic to create xml
}
}
现在为了运行这个方法,我必须这样做:
string xml = GetXML<Roles>(myRoledata);
现在我不知道Type
可能会传给GetXML
方法。我有一种方法可以针对不同的GetXML
调用Type
,例如Roles
,Users
等
现在我可以像Type
一样获得List<>
Type genericType = obj.GetType().GetGenericArguments()[0];
但不能像这样传递
string xml = GetXML<genericType>(myRoledata);
无论如何我可以通过任何genericTypes
到GetXML
方法吗?
答案 0 :(得分:8)
要做到这一点,你需要使用反射;
typeof(SomeClass).GetMethod("GetXML").MakeGenericMethod(genericType)
.Invoke(inst, new object[] {myRoleData});
其中inst
为null
如果是静态方法,this
为当前实例(在这种情况下,您也可以使用GetType()
代替typeof(SomeClass)
}),否则就是目标对象。
答案 1 :(得分:7)
由于您将listdata参数转换为List&lt; T&GT;在方法的第一行,为什么不将方法签名更改为
public string GetXML<T>(List<T> listdata)
这样,您就不必使用反射来获取通用参数。
编辑:我发现你需要能够接受IEnumerable集合,而不仅仅是列表。因此,请考虑将方法签名更改为
public string GetXML<T>(IEnumerable<T> listdata)
答案 2 :(得分:2)
我不知道你的情况,但可以将你的功能重写为:
public string GetXML<T>(IEnumerable<T> listdata)
{
foreach(var obj in listdata)
{
//logic to create xml
}
}
然后它可以被称为:
List<Role> myList;
GetXML(myList);
您可以根据需要添加类型参数以支持它,直到您到达确实知道固体类型的位置。
答案 3 :(得分:2)
这是您可能希望避免解决的问题。 可以通过反射来动态地调用方法而不用静态地解析它们 - 但它有点打败了类型注释的全部要点。
要么这样做:
public string GetXML(IEnumerable listdata) {
foreach(object obj in listdata)
//logic to create xml
}
...您现在可以使用任何IEnumerable
调用,或者将其写为“现代”方式:
public string GetXML(IEnumerable<object> listdata) {
foreach(object obj in listdata)
//logic to create xml
}
...您可以使用任何IEnumerable
通过GetXML(someEnumerable.Cast<object>())
和C#4.0直接通过协方差调用。
如果您需要元素运行时的类型,可以在每个元素上使用.GetType()
获取它,或者您可以将其作为参数传递(并提供向后兼容性的覆盖):
public string GetXML(Type elementType, IEnumerable<object> listdata) {
foreach(object obj in listdata)
//logic to create xml
}
public string GetXML<T>(IEnumerable<T> listdata) {
return GetXML(typeof(T),listdata.Cast<object>());
}
顺便提一下,如果你正在构建XML,那么字符串可能是一个不太健壮的返回类型选择:如果可能的话,你可以使用类似XElement
的东西 - 并获得启动xml-validity保证。
答案 4 :(得分:0)
你有正确的想法,但你使用的是错误的方法。看看Type.MakeGenericType或MethodInfo.MakeGenericMethod。它将比你的例子多几行,但它应该很容易解决。
GetGenericArguments()可用于从List获取角色类型。这是不同的方式。
顺便说一句:看起来你正在实现某种XML序列化。在重新发明轮子之前,请确保检查现有的类。 ; - )