应用于泛型参数超类型的c#typeof

应用于泛型参数超类型的c#typeof,c#,generics,wildcard,typeof,C#,Generics,Wildcard,Typeof,我有一个方法,它没有任何t参数 不幸的是,C#typeof运算符在泛型上不起作用,如下所示 public static string ToString(object obj) { if (obj.GetType() == typeof(List<object>)) { return "Bug: Never called"; } if (obj.GetType() == typeof(List<int>)) {

我有一个方法,它没有任何t参数

不幸的是,C#typeof运算符在泛型上不起作用,如下所示

public static string ToString(object obj)
{
    if (obj.GetType() == typeof(List<object>))
    {
        return "Bug: Never called";
    }
    if (obj.GetType() == typeof(List<int>))
    {
        return "Method only works for int lists";
    }
    return "";
}
公共静态字符串到字符串(对象obj)
{
if(obj.GetType()==typeof(列表))
{
返回“错误:从未调用”;
}
if(obj.GetType()==typeof(列表))
{
return“方法仅适用于int列表”;
}
返回“”;
}
预期输出:ToString(int列表)将返回“Bug:Never Called”

实际输出:“方法仅适用于int列表”

这在Java中运行得非常好。你会说c#中的泛型不支持这一点。如何重新构造代码,使“ToString(object)”方法适用于对象列表

要求:不能修改方法的签名,只能修改其实现

不幸的是,您不能让“int”类实现接口。因为int类是由Microsoft编写的。因此,我不能在int类型上添加访问者模式

不幸的是,c#typeof运算符在泛型上不起作用,如下所示

public static string ToString(object obj)
{
    if (obj.GetType() == typeof(List<object>))
    {
        return "Bug: Never called";
    }
    if (obj.GetType() == typeof(List<int>))
    {
        return "Method only works for int lists";
    }
    return "";
}
事实上,很幸运,它没有像你期望的那样工作。与Java不同,C#在运行时区分
List
List
,而不仅仅是在编译时。使用基元类型参数实例化的泛型的类型信息使.NET可以通过避免类型擦除来生成更高效的代码

如果要测试对象是否为任何通用列表,请改用此检查:

var objT = obj.GetType();
if (objT.IsGenericType && objT.GetGenericTypeDefinition() == typeof(List<>)) {
    ...
}

上面将根据列表中对象的运行时类型选择正确的
进程实现。

为什么希望
列表
返回“Bug:Never Called”,这是
列表
的分支?我不明白为什么希望
列表
对象的类型是
列表
。是的,Java就是这么做的,但C#不是Java。可以说,Java的行为并不是大多数人所期望的。我想您可以使用GetGenericTypeDefinition并与
typeof(List)
进行比较,看看它是否是某个列表。因为object是int的超类。我认为object“捕获”int也是。@MatíasFidemraizer-
object
int
@user2186597的超类-仅仅因为
int
派生自
object
,并不意味着
List
派生自
List
。太好了,你回答了问题的第一部分,为什么c#泛型不能这样工作。现在来看问题的第二部分:我只想统一地操作列表,而不考虑底层类型。任何泛型列表:ddaslinkenlight,这很好,但是如果底层对象不是列表,则强制转换将引发异常。这就是我关注“如果条件”的原因。