Sha*_*ica 10 c# generics typechecking
我有一个字符串序列化实用程序,它接受(几乎)任何类型的变量并将其转换为字符串.因此,例如,根据我的惯例,整数值123将被序列化为"i:3:123"(i =整数; 3 =字符串的长度; 123 =值).
该实用程序处理所有原始类型,以及一些非泛型集合,如ArrayLists和Hashtables.界面是这种形式
public static string StringSerialize(object o) {}
在内部我检测对象是什么类型并相应地序列化它.
现在我想升级我的实用程序来处理泛型集合.有趣的是,我找不到一个合适的函数来检测对象是一个泛型集合,它包含哪些类型 - 我需要哪些信息才能正确序列化.到目前为止,我一直在使用表单的编码
if (o is int) {// do something}
但这似乎不适用于泛型.
您有什么推荐的吗?
编辑:感谢Lucero,我已经接近答案了,但我仍然坚持这个小小的语法难题:
if (t.IsGenericType) {
if (typeof(List<>) == t.GetGenericTypeDefinition()) {
Type lt = t.GetGenericArguments()[0];
List<lt> x = (List<lt>)o;
stringifyList(x);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码无法编译,因为" lt"不允许作为对象的<T>参数List<>.为什么不?什么是正确的语法?
使用"类型"收集所需信息.
对于通用对象,调用GetType()以获取其类型,然后检查IsGenericType以确定它是否是通用的.如果是,你可以得到泛型类型定义,它可以例如像这样进行比较:typeof(List<>)==yourType.GetGenericTypeDefinition().要找出泛型类型是什么,请使用该方法GetGenericArguments,该方法将返回所使用类型的数组.
要比较类型,您可以执行以下操作:if (typeof(int).IsAssignableFrom(yourGenericTypeArgument)).
编辑回答后续行动:
只是让你的stringifyList方法接受一个IEnumerable(不是通用的)参数,也可能是已知的泛型类型参数,你会没事的; 然后,您可以foreach根据类型参数查看所有项目并根据需要进行处理.
重新解决你的难题; 我假设stringifyList是一种通用方法?您需要使用反射调用它:
MethodInfo method = typeof(SomeType).GetMethod("stringifyList")
.MakeGenericMethod(lt).Invoke({target}, new object[] {o});
Run Code Online (Sandbox Code Playgroud)
其中{target}是null用于一个静态方法,或this用于在当前实例的实例方法.
进一步 - 我不会假设所有集合都是:基于List<T>,b:泛型类型.重要的是:他们是否实施IList<T>了一些T?
这是一个完整的例子:
using System;
using System.Collections.Generic;
static class Program {
static Type GetListType(Type type) {
foreach (Type intType in type.GetInterfaces()) {
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IList<>)) {
return intType.GetGenericArguments()[0];
}
}
return null;
}
static void Main() {
object o = new List<int> { 1, 2, 3, 4, 5 };
Type t = o.GetType();
Type lt = GetListType(t);
if (lt != null) {
typeof(Program).GetMethod("StringifyList")
.MakeGenericMethod(lt).Invoke(null,
new object[] { o });
}
}
public static void StringifyList<T>(IList<T> list) {
Console.WriteLine("Working with " + typeof(T).Name);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4516 次 |
| 最近记录: |