我有一个字符串序列化实用程序,它采用(几乎)任何类型的变量并将其转换为字符串。因此,例如,根据我的约定,整数值 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);
  }
}

这段代码无法编译,因为“lt”不允许作为 <T> 对象的 List<> 参数。为什么不?什么是正确的语法?

最佳答案

回复你的难题;我假设 stringifyList 是一个通用方法?您需要通过反射调用它:

MethodInfo method = typeof(SomeType).GetMethod("stringifyList")
            .MakeGenericMethod(lt).Invoke({target}, new object[] {o});

其中 {target} 对于静态方法是 null,对于当前实例的实例方法是 this

此外 - 我不会假设所有集合都是 a: 基于 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);
    }
}

关于c# - 如何检测对象是泛型集合,以及它包含哪些类型?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4769634/

10-14 11:39
查看更多