代码之家  ›  专栏  ›  技术社区  ›  synergetic

在C中检查泛型方法的类型参数#

  •  52
  • synergetic  · 技术社区  · 16 年前

    在C中是否可以这样做?

    public void DoSomething<T>(T t)  
    {
        if (T is MyClass)
        {
            MyClass mc = (MyClass)t 
            ...
        }
        else if (T is List<MyClass>)
        {
            List<MyClass> lmc = (List<MyClass>)t
            ...
        }
    }
    
    4 回复  |  直到 8 年前
        1
  •  88
  •   Jon Skeet    16 年前

    对:

    if (typeof(T) == typeof(MyClass))
    {
        MyClass mc = (MyClass)(object) t;
    }
    else if (typeof(T) == typeof(List<MyClass>))
    {
        List<MyClass> lmc = (List<MyClass>)(object) t;
    }
    

    需要通过强制转换到对象这有点奇怪,但这正是泛型的工作方式——从泛型类型转换的次数并不像您期望的那样多。

    当然,另一种选择是使用正常的执行时间检查:

    MyClass mc = t as MyClass;
    if (mc != null)
    {
        // ...
    }
    else
    {
        List<MyClass> lmc = t as List<MyClass>;
        if (lmc != null)
        {
            // ...
        }
    }
    

    如果 t 当然是空的。

    我愿意 尝试 然而,为了尽可能避免这种代码,有时可能是必要的,但是一般方法的思想是能够编写 通用的 对任何类型使用相同方式的代码。

        2
  •  8
  •   Sousuke    9 年前

    到了2017年,我们现在有了带有模式匹配的C 7。如果您的类型t继承 object 你能这样编码吗

    void Main()
    {
        DoSomething(new MyClass { a = 5 });
        DoSomething(new List<MyClass> { new MyClass { a = 5 }, new MyClass { a = 5 }});
    }
    
    
    public void DoSomething(object t)
    {
        switch (t)
        {
            case MyClass c:
                Console.WriteLine($"class.a = {c.a}");
                break;
            case List<MyClass> l:
                Console.WriteLine($"list.count = {l.Count}");
                break;
        }
    }
    
    class MyClass
    {
        public int a { get; set;}
    }
    
        3
  •  4
  •   mark.monteiro Jack    8 年前

    从C 7开始,您可以使用 is 操作员:

    public void DoSomething<T>(T value)  
    {
        if (value is MyClass mc)
        {
            ...
        }
        else if (value is List<MyClass> lmc)
        {
            ...
        }
    }
    

    见文件: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is#pattern-matching-with-is

        4
  •  3
  •   this. __curious_geek    16 年前

    我相信你的设计有问题。 您希望比较已经通用方法中的类型。泛型是用来处理类型变量情况的。 我建议这样做。

    //Generic Overload 1
    public void DoSomething<T>(T t)
        where T : MyClass
    {
        ...
    }
    
    //Generic Overload 2
    public void DoSomething<T>(T t)
        where T : List<MyClass>
    {
        ...
    }