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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2004508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:33:38  来源:igfitidea点击:

Checking type parameter of a generic method in C#

c#genericstypechecking

提问by synergetic

Is it possible to do something like this in C#:

是否可以在 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
        ...
    }
}

采纳答案by Jon Skeet

Yes:

是的:

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

It's slightly odd that you need to go via a cast to object, but that's just the way that generics work - there aren't as many conversions from a generic type as you might expect.

您需要通过强制转换为对象有点奇怪,但这只是泛型的工作方式 - 泛型类型的转换没有您预期的那么多。

Of course another alternative is to use the normal execution time check:

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

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

That will behave differently to the first code block if tis null, of course.

t当然,如果为 null,则其行为将与第一个代码块不同。

I would tryto avoid this kind of code where possible, however - it can be necessary sometimes, but the idea of generic methods is to be able to write genericcode which works the same way for any type.

然而,我会尽量避免使用这种代码 - 有时可能是必要的,但通用方法的想法是能够编写对任何类型都以相同方式工作的通用代码。

回答by this. __curious_geek

I believe there's something wrong in your design. You want to compare between types in an already generic method. Generics are meant to deal with type-variable situation.I recommend to do it this way..

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

//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>
{
    ...
}

回答by Sousuke

It's 2017 and we have now C# 7 with pattern matching. If your type T inherit objectyou can you code like this

现在是 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;}
}

回答by mark.monteiro

Starting with C# 7, you can do this in a concise way with the isoperator:

从 C# 7 开始,您可以使用is运算符以简洁的方式执行此操作:

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

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

请参阅文档:https: //docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is#pattern-matching-with-is