Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何区分T和IList<;T>;_C#_Generics - Fatal编程技术网

C# 如何区分T和IList<;T>;

C# 如何区分T和IList<;T>;,c#,generics,C#,Generics,我有两种方法: public static int Insert<T>(this System.Data.IDbConnection connection, T param) public static int Insert<T>(this System.Data.IDbConnection connection, IList<T> param) public static int Insert(this System.Data.IDbConnection,

我有两种方法:

public static int Insert<T>(this System.Data.IDbConnection connection, T param)
public static int Insert<T>(this System.Data.IDbConnection connection, IList<T> param)
public static int Insert(this System.Data.IDbConnection,T param)
公共静态int-Insert(此System.Data.IDbConnection连接,IList参数)
当我尝试这样的事情时:

connection.Insert(new List<Foo>());
public static int Insert<T>(this IDbConnection connection, T param) where T: Foo
public static int Insert<T>(this IDbConnection connection, List<T> param)
{
    return connection.Insert((IList<T>)param);
}
connection.Insert(新列表());
调用了错误的方法(第一个方法)


我怎样才能让它工作

如果存在可以以相同方式隐式调用的泛型重载,则必须使用显式调用

此代码将调用第二个重载

connection.Insert<Foo>(new List<Foo>());
connection.Insert(新列表());

您可以指定泛型类型,而不是依赖类型推断

connection.Insert<Foo>(new List<Foo>());
connection.Insert(新列表());
或者,您可以显式强制转换参数以匹配方法的签名,从而对编译器有所帮助

connection.Insert((IList<Foo>)new List<Foo>());
connection.Insert((IList)new List());
此原型:

public static int Insert<T>(this System.Data.IDbConnection connection, T param)

然后,只有当
T
Foo
Foo
的后代时才会调用它。无论是
列表
还是
IList
都不能从
Foo
中降级,这样应该可以解决您的问题。

我看到了以下选项:

  • 若你们不想重写签名方法,你们应该帮助编译器选择特定的重载

    您可以指定泛型参数

    connection.Insert(新列表())

    或强制转换到IList

    connection.Insert((IList)new List())

  • 如果您不想在每次调用该方法时都进行思考,并且可以随意添加更多重载,那么最简单的方法就是为所有可能的
    IList
    实现添加重载,您将使用如下方式:

    connection.Insert(new List<Foo>());
    
    public static int Insert<T>(this IDbConnection connection, T param) where T: Foo
    
    public static int Insert<T>(this IDbConnection connection, List<T> param)
    {
        return connection.Insert((IList<T>)param);
    }
    
    public static int Insert(此IDbConnection连接,列表参数)
    {
    返回连接。插入((IList)参数);
    }
    
  • 如果您根本不想更改公共接口,也不想到处强制转换,则需要更改最通用方法的主体以计算传递的参数,并可能在内部将其传递给其他重载,例如:

    public static int Insert<T>(this IDbConnection connection, T param)
    {
        if (typeof(T).GetInterfaces()
          .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)))
        {
            // method info retrieval should be written more carefully & cached in static var
            var method = MethodBase.GetCurrentMethod().DeclaringType.GetMethods()
              .Single(m => m.Name == "Insert" && m.GetParameters()
                .Select(p => p.ParameterType)
                .Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IList<>)));
            var generic = method.MakeGenericMethod(typeof(T).GenericTypeArguments[0]);
            return (int)generic.Invoke(null, new object[] { connection, param });
        }
    
        ...
    }
    
    public static int Insert(此IDbConnection,T参数)
    {
    if(typeof(T).GetInterfaces()
    .Any(x=>x.IsGenericType&&x.GetGenericTypeDefinition()==typeof(IList)))
    {
    //方法信息检索应该更仔细地编写&缓存在静态var中
    var method=MethodBase.GetCurrentMethod().DeclaringType.GetMethods()
    .Single(m=>m.Name==“插入”&&m.GetParameters()
    .Select(p=>p.ParameterType)
    .Any(t=>t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(IList));
    var generic=method.MakeGenericMethod(typeof(T).GenericTypeArguments[0]);
    return(int)generic.Invoke(null,新对象[]{connection,param});
    }
    ...
    }
    
  • 好吧,如果你不喜欢这一切-只要像.NET团队的那个家伙一样,把重载重命名为
    InsertRange
    或类似的东西就行了。在大多数情况下,如果您正在设计公共图书馆,它是最方便的解决方案

尝试连接。插入(新列表())