Reputation: 48486
I have an IList<object>
where every single object is an instance of a type T
(which I don't know at compile-time).
I need an IList<T>
out of this. I can't use Cast since I don't know the type at compile time, and there isn't a Cast(Type) overload I could use.
This is what I currently have in place:
private object Map(IList<ApiCallContext> bulk)
{
// god-awful way to build a IEnumerable<modelType> list out of Enumerable<object> where object is modelType.
// quoting lead: "think whatever you do it will be ugly"
Type modelType = model.Method.ModelType;
if (bulk.Count > 0)
{
modelType = bulk.First().Parameters.GetType();
}
Type listType = typeof(List<>).MakeGenericType(modelType);
object list = Activator.CreateInstance(listType);
foreach (object value in bulk.Select(r => r.Parameters))
{
((IList)list).Add(value);
}
return list;
}
What I'm thinking about is maybe I could create a new LooseList
class that implements IList
and just works around the casting, seems better than what I currently have but it still sounds way too clunky.
Upvotes: 2
Views: 1190
Reputation: 1500665
If you really need to do exactly as you've stated, I'd first separate this out into "context-specific code" and "reusable code". Effectively you want something like this:
public static IList ToStrongList(this IEnumerable source, Type targetType)
I would implement that by writin a strongly-typed method, and then calling it via reflection:
private static readonly MethodInfo ToStrongListMethod = typeof(...)
.GetMethod("ToStrongListImpl", BindingFlags.Static | BindingFlags.NonPublic);
public static IList ToStrongList(this IEnumerable source, Type targetType)
{
var method = ToStrongListMethod.MakeGenericMethod(targetType);
return (IList) method.Invoke(null, new object[] { source });
}
private static List<T> ToStrongListImpl<T>(this IEnumerable source)
{
return source.Cast<T>().ToList();
}
Upvotes: 4