Dynamic type passing and instantiation -- how? - c#

EDIT: changed Activator, still doesn't work.
So I'm pretty (very) new to C# and I'm pretty sure this is a dupe, but I've looked through the previous questions and I still can't work out all the points.
I am trying to reduce code smell by replacing some repeated code with a map over a generic list. Specifically, I have code that looks like
var fooNode = node as IFoo;
var barNode = node as IBar;
var bazNode = node as IBaz;
...
if(fooNode != null)
return new FooThing();
if(barNode != null)
return new BarThing();
if(bazNode != null)
return new BazThing();
...
and I want to generalise it.
Here's my attempt:
var types = new Dictionary<Type, Type>
{
{typeof(IFoo), typeof(FooThing)},
{typeof(IBar), typeof(BarThing)},
...
}
foreach(var entry in types)
{
var castNode = node as entry.Key;
return Activator.CreateInstance(entry.Value);
}
Naturally, it doesn't work: The type or namespace name 'entry' could not be found (are you missing a using directive or an assembly reference?). Can you help? Is this sort of thing even possible in C#?

How about this?
foreach(var entry in types)
{
if (node != null && entry.Key.IsAssignableFrom(node.GetType()))
{
return Activator.CreateInstance(entry.Value);
}
}
The problem is that you are confusing generic type parameters with runtime types and in particular the Type class.
If you know what a type will be at compile time then you can use the generic Activator.CreateInstance<T>() method to create an instance of the underlying object - you can use things like type parameters so that this line of code doesn't need to know what the type is, for example:
T CreateObject<T>()
{
return Activator.CreateInstance<T>();
}
However this just passes the buck. In order to call this method the value of the type parameter T must be supplied somewhere - either way the compiler must be able to resolve T to a type (rather than a variable or method).
Conversely the Type class encodes type information at runtime such as its name or the assembly that a type is declared in. Activator.CreateInstance also comes with an overload that allows you to supply an instance of Type:
object CreateObject(Type type)
{
return Activator.CreateInstance(type);
}
In your case it looks like you don't know what the types will be at compile time, so you will be mostly working with the Type class - you can use typeof(MyClass) to get an instance of the the corresponding Type for a class known at runtime, and myObject.GetType() to get type information for an object at runtime.

var types = new Dictionary<Type, Type>
{
{typeof(IFoo), typeof(FooThing)},
{typeof(IBar), typeof(BarThing)},
...
}
foreach(var entry in types)
{
if(entry.Key.IsAssignableFrom(node.GetType()))
return Activator.CreateInstance(entry.Value);
}
return null;

Without understanding clearly your purpose for wanting to return different types from the same operation it will be hard to help. Maybe a little background information into the problem you are trying to solve??
I will assume that since you are attempting to return them interchangeably that fooThing, BartThing and BazThing have the same interface. So I am assuming the following:
public class FooThing : IMyOperations
{
}
public class BarThing : IMyOperations
{
}
public class BazThing : IMyOperations
{
}
You can define the relationship between the classes in another interface
public interface IMyChoice
{
public bool IsSelected { get; }
public IMyOperations GetWorker();
}
public class ChoiceFoo : IMyChoice
{
}
public class ChoiceBar : IMyChoice
{
}
public class ChoiceBaz : IMyChoice
{
}
Now you can say
foreach( var entry in choices)
{
if(entry.IsSelected)
{
return entry.GetWorker();
//Can't remember if i need to break after return..doubt it
}
}

Related

How To Get Reflection List<T> Inherited Class [duplicate]

I have a class which uses generic properties. For example:
class Person
{
public MyGenericProperty<string> Field1
{
get { return field1; }
set { field1 = value; }
}
private MyGenericProperty<string> field1= new MyInheritedGenericProperty<string>("Alan1");
}
I want to use this class with reflection at another class and i have a method like that
public void DoSomethingWithProperty(object sourceobject)
{
foreach (var aProperty in sourceobject.GetType().GetProperties())
{
*if(aProperty.PropertyType == typeof(MyGenericProperty<>))*
{
*var obj = (MyGenericProperty<>)aProperty.GetValue(sourceobject, null);*
}
}
return null;
}
I have two problem
1- How can do type check of generic property. In that example code of if(aProperty.PropertyType == typeof(MyGenericProperty<>)) does not work.
2- T of MyGenericProperty could be any class and how can cast MyGenericProperty class without knowing T by reflection as
var obj = (MyGenericProperty<>)aProperty.GetValue(sourceobject, null);
Thank for helps.
Firstly, it's important to understand that you don't have a "generic property" - there's no such thing. You have a property whose type is a generic type... and that's not the same thing. (Compare that with a generic type or a generic method, each of which is genuinely generic in terms of introducing new type parameters.)
You can test it using this code:
if (aProperty.PropertyType.IsGenericType &&
aProperty.GetGenericTypeDefinition() == typeof(MyGenericProperty<>))
But as for the casting - it depends on what you want to do with the value afterwards. You may want to declare a non-generic base type of MyGenericProperty<> containing all the members which don't depend on the type parameter. I'd typically give that the same name as the generic type (e.g. MyGenericProperty) just without giving it type parameters. Then if you only need one of those members, you can use:
if (aProperty.PropertyType.IsGenericType &&
aProperty.GetGenericTypeDefinition() == typeof(MyGenericProperty<>))
{
var value = (MyGenericProperty) aProperty.GetValue(sourceObject, null);
// Use value
}
But then in that case you could use Type.IsAssignableFrom anyway:
if (typeof(MyGenericProperty).IsAssignableFrom(aProperty.PropertyType))
{
var value = (MyGenericProperty) aProperty.GetValue(sourceObject, null);
// Use value
}
If these hints don't help you, please give more details of what you're trying to do.

Generic type inference, Fluent Api, with pre-declared types

I'm working on a Fluent Api for a service which is fairly configurable, and just trying to work my options for a neat solution for the following problem.
I have a class something like this
public class WindowVm : DialogResultBase<MyReturnType>
All well and good, However can any one think of a way to achieve the following without having to verbosely specify the second generic type given i.e
public IDialogWithResult<TViewModel, TSomeReturnType> DialogWithResult<TViewModel,TSomeReturnType>(object owner = null)
where TViewModel : DialogResultBase<TSomeReturnType>
i really am just interest in the result IDialogWithResult<TViewModel, TSomeReturnType> even if i have to do this in 2 statements
So i can call
.DialogWithResult<WindowVm>()
I know all the information is there and declared at compile time, also i know this is Partial Inference and its all or nothing. However i just wondering if there is some trick without having to redeclare
.DialogWithResult<WindowVm, ResultType>();
Moreover i have a method that needs ResultType as (you guessed it) a result type
ResultType MyResult = ...DialogWithResult<WindowVm, ResultType>()
.ShowModal();
I mean, ResultType is really just superfluous at this point in the
game as its already been declared by WindowVm. it would be nice if
the consumer didn't have to go looking for it (even if it meant more
than one step)
Yes, compiler has all the information to infer the type for TSomeReturnType when you pass WindowVm as TViewModel. But the main obstacle for allowing reduced argument list for generic (.DialogWithResult<WindowVm>()) is that it could conflict with overloaded method with the same name but just one generic type argument. For example if you have following methods in the class:
public IDialogWithResult<TViewModel, TSomeReturnType> DialogWithResult<TViewModel,TSomeReturnType>(object owner = null)
where TViewModel : DialogResultBase<TSomeReturnType>
public IDialogWithResult<TViewModel> DialogWithResult<TViewModel>(object owner = null)
where TViewModel : DialogResultBase<MyReturnType>
Which one should compiler call when you code .DialogWithResult<WindowVm>() ?
That's the reason why such simplified syntax will probably not be introduced in C#.
However you still have an option to make the calls as simple as .DialogWithResult<WindowVm>(). I'm not a fan of this solution but if brevity of your Fluent Api calls is important, you could use it. The solution is based on reflection and run-time extraction of TSomeReturnType type from passed TViewModel type:
public class YourClass
{
public dynamic DialogWithResult<TViewModel>(object owner = null)
{
// Searching for DialogResultBase<TSomeReturnType> in bases classes of TViewModel
Type currType = typeof(TViewModel);
while (currType != null && currType != typeof(DialogResultBase<>))
{
if (currType.IsGenericType && currType.GetGenericTypeDefinition() == typeof(DialogResultBase<>))
{
break;
}
currType = currType.BaseType;
}
if (currType == null)
{
throw new InvalidOperationException($"{typeof(TViewModel)} does not derive from {typeof(DialogResultBase<>)}");
}
Type returnValueType = currType.GetGenericArguments()[0];
// Now we know TViewModel and TSomeReturnType and can call DialogWithResult<TViewModel, TSomeReturnType>() via reflection.
MethodInfo genericMethod = GetType().GetMethod(nameof(DialogWithResultGeneric));
if (genericMethod == null)
{
throw new InvalidOperationException($"Failed to find {nameof(DialogWithResultGeneric)} method");
}
MethodInfo methodForCall = genericMethod.MakeGenericMethod(typeof(TViewModel), returnValueType);
return methodForCall.Invoke(this, new [] { owner } );
}
public IDialogWithResult<TViewModel, TSomeReturnType> DialogWithResultGeneric<TViewModel, TSomeReturnType>(object owner = null)
where TViewModel : DialogResultBase<TSomeReturnType>
{
// ...
}
}
We declared new DialogWithResult<TViewModel>() method with just one generic type argument of TViewModel. Then we search for the base DialogResultBase<T> class. If found we extract type of TSomeReturnType with Type.GetGenericArguments() call. And finally call original DialogWithResultGeneric<TViewModel, TSomeReturnType> method via reflection. Note that I have renamed original method to DialogWithResultGeneric so that GetMethod() does not throw AmbiguousMatchException.
Now in your program you could call it as:
.DialogWithResult<WindowVm>()
The downside is that nothing prevents you from calling it on wrong type (the one does not inherit from DialogResultBase<T>):
.DialogWithResult<object>()
You won't get compilation error in this case. The problem will be identified only during run-time when exception will be thrown. You could fix this issue with a technique described in this answer. In short, you should declare non-generic DialogResultBase and set it as the base for DialogResultBase<T>:
public abstract class DialogResultBase
{
}
public class DialogResultBase<T> : DialogResultBase
{
// ...
}
Now you could add constraint on DialogWithResult<TViewModel>() type parameter:
public dynamic DialogWithResult<TViewModel>(object owner = null)
where TViewModel : DialogResultBase
Now .DialogWithResult<object>() will cause compilation error.
Again, I'm not a big fan of solution that I proposed. However you can't achieve what you're asking for with just C# capabilities.
As both you and #CodeFuller observed, partial inference isn't possible in C#.
If you're looking for something less evil than going dynamic, you can use a combination of extension methods and custom classes to get the types you need without ever referring directly to the return type.
In the example below, I use an extension method on DialogResultBase<T> to infer the return type and then I return a helper class containing a generic method for DialogWithResult<WindowVm>.
Still not pretty, but roughly fits what you asked for.
Interesting point about inference. Each parameter can only be used to infer a single type. If you were to pass the same parameter multiple times, you can infer multiple types from it. i.e. if you pass the same parameter to both parameters in (T myList, List<TItem> myListAgain) you could infer both the list type and the item type.
public class Class2
{
public static void DoStuff()
{
var dialogResult = default(WindowVm).GetReturnType().DialogWithResult<WindowVm>();
}
}
public class MyReturnType { }
public class DialogResultBase<T> : IDialogWithResult<T> { }
public interface IDialogWithResult<TSomeReturnType> { }
public class WindowVm : DialogResultBase<MyReturnType> { }
public class DialogResultHelper<TSomeReturnType>
{
public IDialogWithResult<TSomeReturnType> DialogWithResult<TViewModel>() where TViewModel : DialogResultBase<TSomeReturnType>, new()
{
return new TViewModel();
}
}
public static class Extensions
{
public static DialogResultHelper<T> GetReturnType<T>(this DialogResultBase<T> dialogResultBase)
{
return new DialogResultHelper<T>();
}
}

Create an instance of C# generic class [duplicate]

The title is kind of obscure. What I want to know is if this is possible:
string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);
MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();
Obviously, MyGenericClass is described as:
public class MyGenericClass<T>
Right now, the compiler complains that 'The type or namespace 'myType' could not be found." There has got to be a way to do this.
You can't do this without reflection. However, you can do it with reflection. Here's a complete example:
using System;
using System.Reflection;
public class Generic<T>
{
public Generic()
{
Console.WriteLine("T={0}", typeof(T));
}
}
class Test
{
static void Main()
{
string typeName = "System.String";
Type typeArgument = Type.GetType(typeName);
Type genericClass = typeof(Generic<>);
// MakeGenericType is badly named
Type constructedClass = genericClass.MakeGenericType(typeArgument);
object created = Activator.CreateInstance(constructedClass);
}
}
Note: if your generic class accepts multiple types, you must include the commas when you omit the type names, for example:
Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);
Unfortunately no there is not. Generic arguments must be resolvable at Compile time as either 1) a valid type or 2) another generic parameter. There is no way to create generic instances based on runtime values without the big hammer of using reflection.
Some additional how to run with scissors code. Suppose you have a class similar to
public class Encoder() {
public void Markdown(IEnumerable<FooContent> contents) { do magic }
public void Markdown(IEnumerable<BarContent> contents) { do magic2 }
}
Suppose at runtime you have a FooContent
If you were able to bind at compile time you would want
var fooContents = new List<FooContent>(fooContent)
new Encoder().Markdown(fooContents)
However you cannot do this at runtime. To do this at runtime you would do along the lines of:
var listType = typeof(List<>).MakeGenericType(myType);
var dynamicList = Activator.CreateInstance(listType);
((IList)dynamicList).Add(fooContent);
To dynamically invoke Markdown(IEnumerable<FooContent> contents)
new Encoder().Markdown( (dynamic) dynamicList)
Note the usage of dynamic in the method call. At runtime dynamicList will be List<FooContent> (additionally also being IEnumerable<FooContent>) since even usage of dynamic is still rooted to a strongly typed language the run time binder will select the appropriate Markdown method. If there is no exact type matches, it will look for an object parameter method and if neither match a runtime binder exception will be raised alerting that no method matches.
The obvious draw back to this approach is a huge loss of type safety at compile time. Nevertheless code along these lines will let you operate in a very dynamic sense that at runtime is still fully typed as you expect it to be.
My requirements were slightly different, but will hopefully help someone. I needed to read type from a config and instantiate the generic type dynamically.
namespace GenericTest
{
public class Item
{
}
}
namespace GenericTest
{
public class GenericClass<T>
{
}
}
Finally, here is how you call it. Define the type with a backtick.
var t = Type.GetType("GenericTest.GenericClass`1[[GenericTest.Item, GenericTest]], GenericTest");
var a = Activator.CreateInstance(t);
If you know what types will be passed you can do this without reflection. A switch statement would work. Obviously, this would only work in a limited number of cases, but it'll be much faster than reflection.
public class Type1 { }
public class Type2 { }
public class Generic<T> { }
public class Program
{
public static void Main()
{
var typeName = nameof(Type1);
switch (typeName)
{
case nameof(Type1):
var type1 = new Generic<Type1>();
// do something
break;
case nameof(Type2):
var type2 = new Generic<Type2>();
// do something
break;
}
}
}
In this snippet I want to show how to create and use a dynamically created list. For example, I'm adding to the dynamic list here.
void AddValue<T>(object targetList, T valueToAdd)
{
var addMethod = targetList.GetType().GetMethod("Add");
addMethod.Invoke(targetList, new[] { valueToAdd } as object[]);
}
var listType = typeof(List<>).MakeGenericType(new[] { dynamicType }); // dynamicType is the type you want
var list = Activator.CreateInstance(listType);
AddValue(list, 5);
Similarly you can invoke any other method on the list.

How to create instance of a class from class name without using reflection?

Is there any way to achieve something like this?
If "Employee" is passed as an argument to a method it should return an object of type Employee.
But without using reflection.
You could use Type.GetType(string) to get the meta data for the type. However, this requires an Assembly Qualified Name of the type unless the type resides in the currently executing assembly or is part of mscorlib.dll.
Then you can use Activator.CreateInstance(Type) to obtain an instance.
var type = Type.GetType(typeName);
var obj = Activator.CreateInstance(type);
At this point, the static type of obj is System.Object. You would need to continue using reflection to get at the properties and methods defined on your actual type, or you could treat the object as dynamic, assuming you don't know at compile time what class to cast the result to (and if you did know, you would skip this entire process).
Edit: With your added constraint of not wanting to use reflection, this changes your options. The code will not be quite as dynamic in regards to what you can support, you will generally need to have an idea ahead of time, but that might be a good thing, depending on what you are trying to accomplish. What you might have is simply a switch statement or a dictionary that has supported types, keying on the name as a string.
public object GetInstanceOf(string typeName)
{
switch (typeName)
{
case "Employee": return new Employee();
case "Manager" : return new Manager();
case "Owner" : return new Owner();
// etc
default:
throw new InvalidOperationException("typeName is not supported");
}
}
Notice with this approach, you know all of your supported types in advance. There are other ways to know the types in advance outside of code (ex: configuration, data), but those would generally get you back into the land of the first part of the answer. Also note that your return type is still limited. It must be a common base type or interface for the classes involved. In my code sample, it's the common base type for all classes and structs, System.Object. For you, this might be more of a factory, with a Worker base class or IWorker interface. Or maybe Employee is the base and your method is constructing specialized children of it. The latter two examples give you compile-time access to the base or interface defined methods and properties.
Yes than you can do with the help of "Reflection"
Try
Employee employee =(Employee)Activator.CreateInstance("Employee");
check #jon skeet answer : How do I create an instance from a string in C#?
Instantiating an Arbitrary Type Without Reflection
I was wrong. There are a lot of ways that you can instantiate a type without true reflection, it would seem. I'll try to compile a list of all that I can find.
Generics
Depending on what you are trying to do, you might be able to do a very cool technique called generics. You can't input an arbitrary name of a type at runtime, so this doesn't necessarily answer your question in full, but if you know the types that you want at compile time, this makes for a great tool. This involves no reflection of any sort, but is entirely compile time. Here's an example:
interface IParsable
{
bool TryParse(string text);
}
class MyInt : IParsable
{
public int Value { get; private set; }
public static MyInt Parse(string text)
{
Parser parser = new Parser();
return parser.Parse<MyInt>(text);
}
}
class MyFloat : IParsable
{
public float Value { get; private set; }
public static MyFloat Parse(string text)
{
Parser parser = new Parser();
return parser.Parse<MyFloat>(text);
}
}
class Parser
{
// The "new()" constraint means that T must have a
// parameterless constructor.
private T Parse<T>(string text)
where T : IParsable, new()
{
// Even though T isn't actually a type, we can use
// it as if it were, for the most part.
T obj = new T();
// Because we had the IParsable constraint, we can
// use the TryParse method.
if (!obj.TryParse(text))
{
throw new Exception("Text could not be parsed.");
}
return obj;
}
}
Dictionary of Lambdas
Credit to Anthony Pegram for his genius on this one (see comments below). Previously I had this using reflection, but he fixed it to work without any reflection whatsoever, thanks to lambda expressions.
static readonly IDictionary<string, Func<object>> Types = new Dictionary<string, Func<object>>()
{
{ "TypeA", () => new TypeA() },
{ "TypeB", () => new TypeB() },
{ "TypeC", () => new TypeC() },
};
// If you're okay with a bit of reflection behind-the-scenes, change "object"
// here to "dynamic", and you won't have to cast down the road.
object void GetInstance(string name)
{
if (Types.ContainsKey(name))
{
return Types[name]();
}
else
{
return null;
}
}
Pre-Instantiated Objects
Yet another option would be to return the same reference each time. This avoids "true" reflection altogether. This idea of reusing instances has some important implications, which could be either good or bad, depending on what you are doing. These implications are very interesting, and can be quite amazing if used properly.
You could, if you wanted, have each type implement a specific interface, and cast to that, instead of returning a raw object.
static readonly IDictionary<string, object> Instances = new Dictionary<string, object>()
{
{ "TypeA", new TypeA() },
{ "TypeB", new TypeB() },
{ "TypeC", new TypeC() },
};
object void GetInstance(string name)
{
if (!Instances.ContainsKey(name))
{
return null;
}
return Instances[name];
}
Instantiating an Arbitrary Type With Reflection
You've got a nice array of answers that will work great if your type has a parameterless constructor. But what if it doesn't?
const string TYPE = "System.String";
Type type = Type.GetType(TYPE);
if (type == null)
{
// Type doesn't exist--at least, not in mscorlib or current assembly,
// or we didn't specify the assembly.
throw new Exception("Could not find type " + TYPE + ".");
}
// Note the Type array. These are the types of the parameters that the
// constructor takes.
ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(char), typeof(int) });
if (ctor == null)
{
// Constructor doesn't exist that takes those parameters.
throw new Exception("Could not find proper constructor in " + TYPE + ".");
}
// Note the object array. These are the actual parameters passed to the
// constructor. They should obviously match the types specified above.
string result = (string)ctor.Invoke(new object[] { 'a', 5 });
You could use Activator.CreateInstance()
Employee employee =(Employee)Activator.CreateInstance("Namespace", "Employee");
Using reflection as #vulkanino says you will end with something like this:
Employee instance = (Employee)Activator.CreateInstance("MyNamespace.Employee, MyAssembly");
Hope this helps you.
Using reflection you can find types in assemblies, whether it be the executing assembly or other loaded ones (you may load them on demand, actually). Without specifying a complete example of how this might work in your scenario, you would then use something along the lines of Activator.CreateInstance to create instances of your found objects.

Pass An Instantiated System.Type as a Type Parameter for a Generic Class

The title is kind of obscure. What I want to know is if this is possible:
string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);
MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();
Obviously, MyGenericClass is described as:
public class MyGenericClass<T>
Right now, the compiler complains that 'The type or namespace 'myType' could not be found." There has got to be a way to do this.
You can't do this without reflection. However, you can do it with reflection. Here's a complete example:
using System;
using System.Reflection;
public class Generic<T>
{
public Generic()
{
Console.WriteLine("T={0}", typeof(T));
}
}
class Test
{
static void Main()
{
string typeName = "System.String";
Type typeArgument = Type.GetType(typeName);
Type genericClass = typeof(Generic<>);
// MakeGenericType is badly named
Type constructedClass = genericClass.MakeGenericType(typeArgument);
object created = Activator.CreateInstance(constructedClass);
}
}
Note: if your generic class accepts multiple types, you must include the commas when you omit the type names, for example:
Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);
Unfortunately no there is not. Generic arguments must be resolvable at Compile time as either 1) a valid type or 2) another generic parameter. There is no way to create generic instances based on runtime values without the big hammer of using reflection.
Some additional how to run with scissors code. Suppose you have a class similar to
public class Encoder() {
public void Markdown(IEnumerable<FooContent> contents) { do magic }
public void Markdown(IEnumerable<BarContent> contents) { do magic2 }
}
Suppose at runtime you have a FooContent
If you were able to bind at compile time you would want
var fooContents = new List<FooContent>(fooContent)
new Encoder().Markdown(fooContents)
However you cannot do this at runtime. To do this at runtime you would do along the lines of:
var listType = typeof(List<>).MakeGenericType(myType);
var dynamicList = Activator.CreateInstance(listType);
((IList)dynamicList).Add(fooContent);
To dynamically invoke Markdown(IEnumerable<FooContent> contents)
new Encoder().Markdown( (dynamic) dynamicList)
Note the usage of dynamic in the method call. At runtime dynamicList will be List<FooContent> (additionally also being IEnumerable<FooContent>) since even usage of dynamic is still rooted to a strongly typed language the run time binder will select the appropriate Markdown method. If there is no exact type matches, it will look for an object parameter method and if neither match a runtime binder exception will be raised alerting that no method matches.
The obvious draw back to this approach is a huge loss of type safety at compile time. Nevertheless code along these lines will let you operate in a very dynamic sense that at runtime is still fully typed as you expect it to be.
My requirements were slightly different, but will hopefully help someone. I needed to read type from a config and instantiate the generic type dynamically.
namespace GenericTest
{
public class Item
{
}
}
namespace GenericTest
{
public class GenericClass<T>
{
}
}
Finally, here is how you call it. Define the type with a backtick.
var t = Type.GetType("GenericTest.GenericClass`1[[GenericTest.Item, GenericTest]], GenericTest");
var a = Activator.CreateInstance(t);
If you know what types will be passed you can do this without reflection. A switch statement would work. Obviously, this would only work in a limited number of cases, but it'll be much faster than reflection.
public class Type1 { }
public class Type2 { }
public class Generic<T> { }
public class Program
{
public static void Main()
{
var typeName = nameof(Type1);
switch (typeName)
{
case nameof(Type1):
var type1 = new Generic<Type1>();
// do something
break;
case nameof(Type2):
var type2 = new Generic<Type2>();
// do something
break;
}
}
}
In this snippet I want to show how to create and use a dynamically created list. For example, I'm adding to the dynamic list here.
void AddValue<T>(object targetList, T valueToAdd)
{
var addMethod = targetList.GetType().GetMethod("Add");
addMethod.Invoke(targetList, new[] { valueToAdd } as object[]);
}
var listType = typeof(List<>).MakeGenericType(new[] { dynamicType }); // dynamicType is the type you want
var list = Activator.CreateInstance(listType);
AddValue(list, 5);
Similarly you can invoke any other method on the list.

Categories