This question already has answers here:
How do I use reflection to call a generic method?
(8 answers)
Closed 8 years ago.
I have a method with the following signature:
private string SerialiazeObj<T>(T obj)
{
// Do some work
}
Now, I have another method which accepts an object and calls the SerializeObj method, as shown below:
private void callSerializeObj(object obj)
{
Type objType = obj.GetType();
string s = SerialiazeObj<objType>((objType)obj));
}
The object passed to callSerializeObj can be of any type. Unfortunately, the compiler is giving me this error in the (string s = SerializeObj...) part:
The type or namespace 'objType' could not be found (are you missing an assembly reference).
I don't know if I am calling SerializeObj the correct way. What is the correct way of calling the method with an object which can be of any type?
Use as below -
private void callSerializeObj(object obj)
{
Type objType = obj.GetType();
MethodInfo method = this.GetType().GetMethod("SerialiazeObj", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo generic = method.MakeGenericMethod(objType );
object Result = generic.Invoke(this, new object[] { obj });
}
Related
This question already has answers here:
Convert IEnumerable to IEnumerable<T> when T isn't known until runtime
(2 answers)
Closed 5 years ago.
This is a weird problem that I've stumbled upon, involving reflection:
I create a MyGenericType<T> at runtime where T is a runtime type:
object genType = Activator.CreateInstance(typeof(MyGenericType<>).MakeGenericType(runtimeType));
Then I need to pass it as an argument to another function which only accepts a IEnumerable<runtimeType>.
I can't use dynamic as MyGenericType only implements IEnumerable explicitly, not implicitly.
Is there anyway to cast to an IEnumerable<runtimeType>?
Create a generic caller method and invoke that instead. In my code sample, the CallMethod is invoked via reflection and that method invokes the method that takes an IEnumerable<T>
static void Main(string[] args)
{
Type runtimeType = typeof(string);
object genType = Activator.CreateInstance(typeof(MyGenericType<>).MakeGenericType(runtimeType));
var genericMethod = ((Action<MyGenericType<object>>)CallMethod)
.Method
.GetGenericMethodDefinition()
.MakeGenericMethod(runtimeType)
.Invoke(null, new object[] { genType });
}
static void CallMethod<T>(MyGenericType<T> myGeneric)
{
MyEnumerableMethod((IEnumerable<T>)myGeneric);
}
This question already has answers here:
How do I use reflection to call a generic method?
(8 answers)
Closed 6 years ago.
Is it possible to make such code work?:
private List<Type> Models = new List<Type>()
{
typeof(LineModel), typeof(LineDirectionModel), typeof(BusStopTimeModel), typeof(BusStopNameModel)
};
foreach (Type model in Models) // in code of my method
{
Connection.CreateTable<model>(); // error: 'model' is a variable but is used like a type
}
Thanks in advance
You won't be able to use the variable as a generic type using the conventional syntax (CreateTable<model>). Without knowing what CreateTable does, you have two options:
Instead of making CreateTable a generic method, have it take the type as a parameter:
public static void CreateTable(Type modelType)
{
}
Use Reflection to dynamically invoke the generic method using the desired type:
var methodInfo = typeof (Connection).GetMethod("CreateTable");
foreach (Type model in Models)
{
var genericMethod = methodInfo.MakeGenericMethod(model);
genericMethod.Invoke(null, null); // If the method is static OR
// genericMethod.Invoke(instanceOfConnection, null); if it's not static
}
Note that the reflection way would be slower since the method info won't be resolved until runtime.
You can do it like this,
private List<Type> Models = new List<Type>()
{
typeof(LineModel), typeof(LineDirectionModel), typeof(BusStopTimeModel), typeof(BusStopNameModel)
};
void SomeMethod()
{
MethodInfo genericFunction =Connection.GetType().GetMethod("CreateTable");
foreach (Type model in Models)
{
MethodInfo realFunction = genericFunction.MakeGenericMethod(model);
var ret = realFunction.Invoke(Connection, new object[] { });
}
}
This question already has answers here:
Using Type objects as Type Parameters for Generics in C#
(2 answers)
Closed 9 years ago.
How can I use a Type object as a Type argument?
For example:
byte[] Data;
Type objectType;
public T MyFunction<T>()
{
return OtherClass.Deserialize <objectType> (Data);
}
In other words, how do you use a Type object in a Type parameter <typehere>?
Your generic method expects type identifier which is known at compile time. Meanwhile, you're trying to pass an instance of such a type to your method, but such an instance is not known until runtime.
Use reflection instead:
var method = typeof (OtherClass).GetMethods()
.Single(x => "Deserialize".Equals(x.Name)
&& x.IsGenericMethodDefinition);
method = method.MakeGenericMethod(new[] { objectType });
method.Invoke(null, new object[] { Data });
Generics is really designed to work with types which are known at compile-time on the calling side. (The type argument can itself be a type parameter as far as the caller is concerned, of course.)
Otherwise, you're stuck with generics - you'd get the MethodInfo associated with OtherClass.Deserialize, call MakeGenericMethod using objectType as an argument, and then call the resulting method.
var method = typeof(OtherClass).GetMethod("Deserialize");
var genericMethod = method.MakeGenericMethod(objectType);
object result = genericMethod.Invoke(null, Data);
Note that this won't return a T though. It's not clear why your MyFunction method is generic if you're not actually going to use the type parameter.
Like this (recursively, for brevity):
Type myType;
public void MyFunction<T>(T instance) {
MyFunction<Type>(myType);
}
here myType is a Type object. So you should call MyFunction<Type>( myType);
You should write MyFunction method like:
public T MyFunction<T>(byte[] data)
{
return OtherClass.Deserialize<T>(data);
}
and the client code will look like:
byte[] Data = new byte[];
Type objectType;
objectType = MyFunction<Type>(Data);
This question already has answers here:
How do I use reflection to call a generic method?
(8 answers)
Closed 8 years ago.
It is strange but the source code
public class Processor<T> where T: class
{
...
private object WorkWithSubtype(IRequester nextRequester, Type type)
{
if (type.GetInterface("IList") != null)
{
var originalType = type.GetGenericArguments()[0];
var list = Activator.CreateInstance(type);
var method = typeof(Processor<>).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType);
var resList = method.Invoke(this, new object[] { nextRequester });
typeof(List<>).GetMethod("AddRange").MakeGenericMethod(originalType).Invoke(list, new object[] { resList });
return list;
}
}
private IEnumerable<K> GetObjects<K>(IRequester requester) where K: class
{
...
//We can call method WorkWithSubtype in this method sometimes
}
}
And i get "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.". The exception is throwing at line 'var resList = method.Invoke(this, new object[] { nextRequester });'. Can you help me? Thanks in advance!
You have two generic parameters: one is for the Processor class; the other is for the GetObjects method. In making the generic method, you've supplied a type argument for the method's type parameter, but you haven't supplied a type argument for the class's generic parameter.
Depending on the purpose of the processor class, you could try one of the following solutions:
build the closed generic type with a type argument
use typeof(Processor<T>) rather than using reflection to build the closed generic type
remove the type parameter from the class
remove the type parameter from the method
I think the second is most likely to be what you're looking for:
var method = typeof(Processor<T>)
.GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance)
.MakeGenericMethod(originalType);
Additionally, AddRange is not a generic method; rather, List<> is a generic type, so:
typeof(List<>)
.MakeGenericType(originalType)
.GetMethod("AddRange")
.Invoke(list, new object[] { resList });
You need to use MakeGenericType like so:
var method = typeof(Processor<>).MakeGenericType(typeof(T)).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType);
similarly when you invoke the AddRange method.
The problem is that List<string>.AddRange is a different method than List<int>.AddRange and MakeGenericType applies the type parameter to the class. Calling MakeGenericMethod is still required for GetObjects since it has a different generic type parameter (K) than the containing class (T).
This question already has answers here:
How do I use reflection to call a generic method?
(8 answers)
Closed 9 years ago.
I have:
class Car {..}
class Other{
List<T> GetAll(){..}
}
I want to do:
Type t = typeof(Car);
List<t> Cars = GetAll<t>();
How can I do this?
I want to return a generic collection from the database of a type that I discover at runtime using reflection.
Type generic = typeof(List<>);
Type specific = generic.MakeGenericType(typeof(int));
ConstructorInfo ci = specific.GetConstructor(Type.EmptyTypes);
object o = ci.Invoke(new object[] { });
You could use reflection for this:
Type t = typeof(Car);
System.Type genericType= generic.MakeGenericType(new System.Type[] { t});
Activator.CreateInstance(genericType, args);