Jon*_*Jon 72 c# generics types
我有一个使用a IList<T>作为参数的方法.我需要检查该T对象的类型是什么,并根据它做一些事情.我试图使用该T值,但编译器不允许它.我的解决方案如下:
private static string BuildClause<T>(IList<T> clause)
{
    if (clause.Count > 0)
    {
        if (clause[0] is int || clause[0] is decimal)
        {
           //do something
        }
        else if (clause[0] is String)
        {
           //do something else
        }
        else if (...) //etc for all the types
        else
        {
           throw new ApplicationException("Invalid type");
        }
    } 
}
必须有更好的方法来做到这一点.有什么方法可以检查T传入的类型然后使用switch语句?
jon*_*nii 104
你可以使用重载:
public static string BuildClause(List<string> l){...}
public static string BuildClause(List<int> l){...}
public static string BuildClause<T>(List<T> l){...}
或者您可以检查泛型参数的类型:
Type listType = typeof(T);
if(listType == typeof(int)){...}
bdo*_*den 19
你可以用typeof(T).
private static string BuildClause<T>(IList<T> clause)
{
     Type itemType = typeof(T);
     if(itemType == typeof(int) || itemType == typeof(decimal))
    ...
}
Jai*_*der 11
我希望你觉得这有帮助:
typeof(IList<T>).IsGenericType == truetypeof(IList<T>).GetGenericTypeDefinition() == typeof(IList<>)typeof(IList<int>).GetGenericArguments()[0] == typeof(int)https://dotnetfiddle.net/5qUZnt
而且,由于 C# 已经发展,您(现在)可以使用模式匹配。
private static string BuildClause<T>(IList<T> clause)
{
    if (clause.Count > 0)
    {
        switch (clause[0])
        {
            case int x: // do something with x, which is an int here...
            case decimal x: // do something with x, which is a decimal here...
            case string x: // do something with x, which is a string here...
            ...
            default: throw new ApplicationException("Invalid type");
        }
    }
}
再次使用C# 8.0 中的switch 表达式,语法变得更加简洁。
private static string BuildClause<T>(IList<T> clause)
{
    if (clause.Count > 0)
    {
        return clause[0] switch
        {
            int x => "some string related to this int",
            decimal x => "some string related to this decimal",
            string x => x,
            ...,
            _ => throw new ApplicationException("Invalid type")
        }
    }
}
默认情况下,知道没有一个好方法.一段时间后,我对此感到沮丧,写了一个小实用程序类,帮助了一点,使语法更清晰.基本上它将代码转换为
TypeSwitcher.Do(clause[0],
  TypeSwitch.Case<int>(x => ...),  // x is an int
  TypeSwitch.Case<decimal>(d => ...), // d is a decimal 
  TypeSwitch.Case<string>(s => ...)); // s is a string
完整的博客文章和有关实施的详细信息可在此处获得