Wpf Dispatcher {"The Calling Thread Cannot Access This Object Because a Different Thread Owns It."}

Dynamically Create a generic type for template

What you are looking for is MakeGenericType

string elementTypeName = Console.ReadLine();
Type elementType = Type.GetType(elementTypeName);
Type[] types = new Type[] { elementType };

Type listType = typeof(List<>);
Type genericType = listType.MakeGenericType(types);
IProxy proxy = (IProxy)Activator.CreateInstance(genericType);

So what you are doing is getting the type-definition of the generic "template" class, then building a specialization of the type using your runtime-driving types.

Create instance of generic class with dynamic generic type parameter

I found very simple solution to problem. There is no need to cast object to specific type T, just use dynamic keyword instead of casting

   Type myGeneric = typeof(MyComparer<>);
Type constructedClass = myGeneric.MakeGenericType(T);
object created = Activator.CreateInstance(constructedClass);
dynamic comparer = created; // No need to cast created object to T

and then I can use comparer normally to call its methods like:

   return comparer.Equals(myResultAsT, correctResultAsT);

According to LueTm comments, it is probably possible to use reflection again and call comparer methods, but this solution looks much easier.

How to dynamically create generic C# object using reflection?

Check out this article and this simple example. Quick translation of same to your classes ...

var d1 = typeof(Task<>);
Type[] typeArgs = { typeof(Item) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);

Per your edit: For that case, you can do this ...

var d1 = Type.GetType("GenericTest.TaskA`1"); // GenericTest was my namespace, add yours
Type[] typeArgs = { typeof(Item) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);

To see where I came up with backtick1 for the name of the generic class, see this article.

Note: if your generic class accepts multiple types, you must include the commas when you omit the type names, for example:

Type type = typeof(IReadOnlyDictionary<,>);

Pass dynamically type to generic template

Lets say CreateManager<T> is a method of type Foo:

public class Foo
{
private void CreateManager<T>(ServiceProvider serviceProvider,
DeviceCapability deviceCapability)
{
}
}

In order to dynamically invoke the generic method, you'll need to get the MethodInfo first, then call MakeGenericMethod with the actual type you want to pass (I choose string for the example)

var foo = new Foo();
var createManagerMethod = foo.GetType()
.GetMethod("CreateManager",
BindingFlags.Instance | BindingFlags.NonPublic);

var method = createManagerMethod.MakeGenericMethod(typeof(string));
method.Invoke(foo, new object[] { new ServiceProvider(), new DeviceCapability() });

Finally, call Invoke with the proper object instance and parameters.

Declare a generic type instance dynamically

If you don't know the type at compile-time, but you want the actual type (i.e. not List<object>) and you're not in a generic method/type with the appropriate type parameter, then you have to use reflection.

To make the reflection simpler, I've sometimes introduced a new generic type or method in my own code, so I can call that by reflection but then just use normal generics after that. For example:

object x = GetObjectFromSomewhere();
// I want to create a List<?> containing the existing
// object, but strongly typed to the "right" type depending
// on the type of the value of x
MethodInfo method = GetType().GetMethod("BuildListHelper");
method = method.MakeGenericMethod(new Type[] { x.GetType() });
object list = method.Invoke(this, new object[] { x });

// Later

public IList<T> BuildListHelper<T>(T item)
{
List<T> list = new List<T>();
list.Add(item);
return list;
}

Of course, you can't do an awful lot with the list afterwards if you don't know the type... that's why this kind of thing often falls down. Not always though - I've used something like the above on a few occasions, where the type system just doesn't quite let me express everything I need to statically.

EDIT: Note that although I'm calling Type.GetMethod in the code above, if you were going to execute it a lot you'd probably want to just call it once - after all, the method isn't going to change. You may be able to make it static (you could in the case above) and you probably want to make it private too. I left it as a public instance method for the simplicity of the GetMethod call in sample code - you'd need to specify the appropriate binding flags otherwise.

Passing an instance of a dynamic type to a generic method in a generic class

To answer your question:

var type = typeof(abc);
object instanceToModify = new abc();

var typeToCreate = typeof(GenericClass<>).MakeGenericType(type);
var methodToCall = typeToCreate.GetMethod("GenericMethod");

var genericClassInstance = Activator.CreateInstance(typeToCreate);
methodToCall.Invoke(genericClassInstance, new[] { instanceToModify });

DEMO

But:

If your type is only known at runtime your instance must be handled in a variable declared as object or dynamic. In that case you can change your method signature to:

public object GenericMethod(object obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (var field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}

return obj;
}

There's no need for a generic class/method.

How can i create generic dynamic array?

I figured it out;

template<class T>
class List {

private:
T* first_cell = nullptr;
int size = 0; // currently occupied elements
int capacity = 8; // size of the allocated memory

public:
List() {
first_cell = new T[capacity]; // Declare the array in memory
}

List(const List& src)
: size(src.size),
capacity(src.capacity)
{
first_cell = new T[capacity];
std::copy_n(src.first_cell, size, first_cell);
}

List(List&& src)
: first_cell(src.first_cell),
size(src.size),
capacity(src.capacity)
{
src.first_cell = nullptr;
src.size = src.capacity = 0;
}

~List() {
delete[] first_cell;
}

List& operator=(List rhs) {
List temp(std::move(rhs));
std::swap(first_cell, temp.first_cell);
std::swap(size, temp.size);
std::swap(capacity, temp.capacity);
return *this;
}

void push_back(int number) {
if (size == capacity) {
int new_cap = capacity * 2; // increased capacity
T* new_arr = new T[new_cap]; // new arr with new capacity

for (int k = 0; k < size; ++k) {
new_arr[k] = first_cell[k]; // copy data from frist array
}

delete[] first_cell; // remove first array

first_cell = new_arr;
capacity = new_cap;
}
first_cell[size] = number;
++size;
}

int length() {
return size;
}

int first_index_of(int number) {
for (int k = 0; k < size; k++) {

if (number == first_cell[k]) {

return k;
}
}
return -1;
}

void print(char symb) {
for (int k = 0; k < size; ++k) {
std::cout << first_cell[k] << symb;
}
}
};

Ninject: How To Dynamically Inject Generic Type into Bound Template Object

Of course this works, it's very simple:

foreach(Type genericType in repositoryTypes)
{
object tempRepository = WebManager.Get(typeof(IRepository).MakeGenericType(genericType));
//do stuff with tempRepository
}

But then it get's trickier. How will you use this object? You'll need to use reflection. It's simpler to use it once than for every call. So we can adjust/write the code as follows:

internal class Foo
{
private static readonly MethodInfo DoStuffToRepositoryForMethod =
typeof(Foo).GetMethod(
"DoStuffToRepositoryFor",
BindingFlags.Instance | BindingFlags.NonPublic);

private readonly IResolutionRoot resolutionRoot;

public Foo(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}

public void DoStuffToRepositories(params Type[] entityTypes)
{
foreach (Type entityType in entityTypes)
{
MethodInfo doStuffMethod = DoStuffToRepositoryForMethod
.MakeGenericMethod(entityType);
doStuffMethod.Invoke(this, new object[0]);
}
}

private void DoStuffToRepositoryFor<T>()
{
var repository = this.resolutionRoot.Get<IRepository<T>>();
repository.DoSomething();
}
}

and just for reference, this is a test showing that it works:

public class Test
{
[Fact]
public void TestIt()
{
var kernel = new StandardKernel();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));

var foo = kernel.Get<Foo>();

foo.DoStuffToRepositories(typeof(string), typeof(int));
}
}

Don't employ magic if you don't have to

But i think the more important question is: why do you want to do this?
How do you know the list of entity types and entities to do something for?
In most cases there's an alternative way which doesn't involve that much "magic".



Related Topics



Leave a reply



Submit