I have this code that correctly discovers all the classes in my assembly implementing the interface I need, but because they are all of generic types, I can't instantiate them. For some of these the type is known and hardcoded but for others, it's user supplied:
public void DiscoverImples()
{
var type = typeof(IOperator<,>);
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => GetAllTypesImplementingOpenGenericType(type, a)).Select(Activator.CreateInstance).ToList();
Console.WriteLine(types);
}
public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly)
{
return from x in assembly.GetTypes()
from z in x.GetInterfaces()
let y = x.BaseType
where
(y != null && y.IsGenericType && openGenericType.IsAssignableFrom(y.GetGenericTypeDefinition())) ||
(z.IsGenericType && openGenericType.IsAssignableFrom(z.GetGenericTypeDefinition())) &&
(!x.IsAbstract)
select x;
}
The error I receive is:
System.ArgumentException
HResult=0x80070057
Message=Cannot create an instance of FlightChangeService.Application.Operators.EqualOperator`1[T] because Type.ContainsGenericParameters is true.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeType.CreateInstanceCheckThis()
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type)
at System.Linq.Enumerable.SelectEnumerableIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
In this case, the Operator it's complaining about is
public interface IOperator<in T, out TResult>
public abstract class AbstractOperator<T, TOutput> : IOperator<T, TOutput>
public abstract class LogicalOperator<T> : AbstractOperator<T, bool>
public sealed class EqualOperator<T> : LogicalOperator<IEquatable<T>>
For what I am trying to do, I have to push off until runtime the type casting. Should I just ditch generics all together and assume everything is an object
and type cast in the implementation?
User contributions licensed under CC BY-SA 3.0