Can I use a type of reflection as a parameter type?

Is it possible to use a type of reflection as a parameter type? For instance. I want to choose persister, based on the transmitted object:

IPersister GetPersisterFor(IEntity entity) { return GetPersisterFor<entity.GetType()>(); // <-- this cannot be compiled } IPersister GetPersisterFor<TEntity>() where TEntity : IEntity { //some logic to get persister... } 
+4
source share
3 answers

It is only through reflection; you will need to use GetMethod , to get a MethodInfo for a general method, then type MakeGenericMethod(entity.GetType()).Invoke(this, null); this, null).; .

However, it’s easier to spoof the dynamic:

 IPersister Evil<T>(T obj) where T : IEntity { return GetPersisterFor<T>(); } ) where T: IEntity { IPersister Evil<T>(T obj) where T : IEntity { return GetPersisterFor<T>(); } 

And take the first method is simply:

 return Evil((dynamic)entity); 

This dynamic expression that will determine the right to use the T (for Evil-of-T call) for you.

Note. The only reason that you need an additional method - to make sure it does not solve recursively, because the names are the same.

+4
source

Yes, you need to get the definition of the general method. Then you can use MethodInfo.MakeGenericMethod to create a common method.

So something like:

 MethodInfo genericMethodDefinition = GetType() .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .Where(method => method.IsGenericMethod && method.Name == "GetPersisterFor") .First(); // OR MethodInfo genericMethodDefinition = GetType().GetMethod("GetPersisterFor", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null); // THEN MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(entity.GetType()); genericMethod.Invoke(this, null); == "GetPersisterFor") MethodInfo genericMethodDefinition = GetType() .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .Where(method => method.IsGenericMethod && method.Name == "GetPersisterFor") .First(); // OR MethodInfo genericMethodDefinition = GetType().GetMethod("GetPersisterFor", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null); // THEN MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(entity.GetType()); genericMethod.Invoke(this, null); ( "GetPersisterFor", MethodInfo genericMethodDefinition = GetType() .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .Where(method => method.IsGenericMethod && method.Name == "GetPersisterFor") .First(); // OR MethodInfo genericMethodDefinition = GetType().GetMethod("GetPersisterFor", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null); // THEN MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(entity.GetType()); genericMethod.Invoke(this, null); ); MethodInfo genericMethodDefinition = GetType() .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .Where(method => method.IsGenericMethod && method.Name == "GetPersisterFor") .First(); // OR MethodInfo genericMethodDefinition = GetType().GetMethod("GetPersisterFor", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null); // THEN MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(entity.GetType()); genericMethod.Invoke(this, null); 
+1
source

Since both common and general methods have the same name, you have to go through all the methods of a class to find the right, and then call it:

 public IPersister GetPersisterFor(IEntity entity) { MethodInfo getPersisterForGenericMethod = GetType().GetMethods() // iterate over all methods to find proper generic implementation .Single(methodInfo => methodInfo.Name == "GetPersisterFor" && methodInfo.IsGenericMethod) // supply it with generic type parameter .MakeGenericMethod(entity.GetType()); // invoke it return getPersisterForGenericMethod.Invoke(this, null) as IPersister; } public IPersister GetPersisterFor<TEntity>() where TEntity : IEntity { return null; } generic implementation public IPersister GetPersisterFor(IEntity entity) { MethodInfo getPersisterForGenericMethod = GetType().GetMethods() // iterate over all methods to find proper generic implementation .Single(methodInfo => methodInfo.Name == "GetPersisterFor" && methodInfo.IsGenericMethod) // supply it with generic type parameter .MakeGenericMethod(entity.GetType()); // invoke it return getPersisterForGenericMethod.Invoke(this, null) as IPersister; } public IPersister GetPersisterFor<TEntity>() where TEntity : IEntity { return null; } GetPersisterFor" && methodInfo.IsGenericMethod) public IPersister GetPersisterFor(IEntity entity) { MethodInfo getPersisterForGenericMethod = GetType().GetMethods() // iterate over all methods to find proper generic implementation .Single(methodInfo => methodInfo.Name == "GetPersisterFor" && methodInfo.IsGenericMethod) // supply it with generic type parameter .MakeGenericMethod(entity.GetType()); // invoke it return getPersisterForGenericMethod.Invoke(this, null) as IPersister; } public IPersister GetPersisterFor<TEntity>() where TEntity : IEntity { return null; } where TEntity: IEntity public IPersister GetPersisterFor(IEntity entity) { MethodInfo getPersisterForGenericMethod = GetType().GetMethods() // iterate over all methods to find proper generic implementation .Single(methodInfo => methodInfo.Name == "GetPersisterFor" && methodInfo.IsGenericMethod) // supply it with generic type parameter .MakeGenericMethod(entity.GetType()); // invoke it return getPersisterForGenericMethod.Invoke(this, null) as IPersister; } public IPersister GetPersisterFor<TEntity>() where TEntity : IEntity { return null; } 

ps: the complete source code is available gist.github

+1
source

All Articles