How to distinguish between T and IList <T>
I have two methods:
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)
When I try something like this:
connection.Insert(new List<Foo>());
the wrong method is called (first method).
How can I make it work?
+4
4 answers
This prototype:
public static int Insert<T>(this System.Data.IDbConnection connection, T param)
... will accept almost everything as param, because it has type restrictions on it. He will accept Foo, a IList<Foo>, a List<Foo>and all not Foo. Thus, it overrides the second prototype, a problem known as convergence.
, . , , :
public static int Insert<T>(this IDbConnection connection, T param) where T: Foo
, T Foo Foo. List<>, IList<> Foo, .
+2
:
, .
connection.Insert<Foo>(new List<Foo>());IList<T>:connection.Insert((IList<Foo>)new List<Foo>());, , - -
IList, :public static int Insert<T>(this IDbConnection connection, List<T> param) { return connection.Insert((IList<T>)param); }- , , , - :
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 }); } ... }, - , .NET
InsertRange- . , .
+1