Create instance of generic type whose constructor requires a parameter?
Additionally a simpler example:
return (T)Activator.CreateInstance(typeof(T), new object[] { weight });
Note that using the new() constraint on T is only to make the compiler check for a public parameterless constructor at compile time, the actual code used to create the type is the Activator class.
You will need to ensure yourself regarding the specific constructor existing, and this kind of requirement may be a code smell (or rather something you should just try to avoid in the current version on c#).
How to create an instance of generic type whose constructor requires a delegate function parameter?
Constructing a delegate of an unknown type dynamically isn't as easy as using reflection to call a method, so the easiest option is to just write a statically typed method to construct the delegate, and then just call it using reflection.
public class DelegateCreator
{
public static Func<T> MakeConstructorStatically<T>()
{
return Activator.CreateInstance<T>;
}
public static object MakeConstructorDynamically(Type type)
{
return typeof(DelegateCreator)
.GetMethod(nameof(MakeConstructorStatically))
.MakeGenericMethod(type)
.Invoke(null, Array.Empty<object>());
}
}
Create Instance of Generic Type
You should use: CreateInstance(typeof(T))
, typeof
returns an object of class System.Type
which will work.
There is a difference in C# between a 'Generic' type T
and an instance of System.Type
. Activator.CreateInstance requires the latter.
Edit: You should generally use DavidG's method, it is cleaner. You can use the Activator
when:
- You can't add a generic constraint for some reason.
- You want to pass arguments to the constructor. (the
new()
constraint implies a parameterless constructor, with theActivator
you can pass parameters.)
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.
Create instance of a generic type that takes a parameter a secondary generic type
After Abion47 pointed out that Activator.CreateInstance shouldn't have any issues doing what I need it to do I looked a bit more into the issue and made it work.
For anyone that might come across this:
public abstract class Sentinel<T,U> where T: new() where U: new()
{
public T CreateModel(IDictionary<String, Object> parametersDictionary)
{
T toReturn ;
if (ValidateDictionary(parametersDictionary) != true)
return default(T);
else
{
U parameters = ParseDictionaryToParameters(parametersDictionary);
toReturn = (T)Activator.CreateInstance(typeof(T), new object[] {parameters});
}
//If we got this far then everything should be fine.
return toReturn;
}
public abstract U ParseDictionaryToParameters(IDictionary<String, Object> parametersDictionary);
public abstract Boolean ValidateDictionary(IDictionary<String, Object> parametersDictionary);
}
Create instance of class with generic type and call method of same generic type from string name of object at runtime
Your wrapper got the following signature:
public class MyClass<T> where T : class, new()
it basically says "T needs to be a class and have a default constructor". The interesting part is about the default constructor. It means that the class must have a constructor with no arguments.
It tells .NET that you can invoke:
var obj = new T();
So the first step is to do just that:
public class MyClass<T> where T : class, new()
{
public IList<T> MyMethod(Stream stream)
{
var data = new List<T>();
//this
var obj = new T();
return data;
}
}
next you wanted to invoke a method. That's done with the help of reflection.
A simple example is:
var obj = new T();
//get type information
var type = obj.GetType();
//find a public method named "DoStuff"
var method = type.GetMethod("DoStuff");
// It got one argument which is a string.
// .. so invoke instance **obj** with a string argument
method.Invoke(obj, new object[]{"a string argument"});
Update
I missed the important part:
I need to return my IList from the MyMethod() method based on the name of the object I'm passing in as a string.
If the type is declared in the same assembly as your executing code you can just pass the full type name like Some.Namespace.ClassName" to
Type.GetType()`:
var type = Type.GetType("Some.Namespace.ClassName");
var obj = Activator.CreateInstance(type);
If the class is declared in another assembly you need to specify it:
var type = Type.GetType("Some.Namespace.ClassName, SomeAsseblyName");
var obj = Activator.CreateInstance(type);
The rest is pretty much the same.
If you only have the class name you can traverse the assembly to find the correct type:
var type = Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(x => x.Name == "YourName");
var obj = Activator.CreateInstance(type);
Issue activating a generic type with generic array in constructor parameters
I can tell you what happens. Having a look at the resulting assembly you can see that the compiler introduces an object[]
wrapping the values
argument:
Activator.CreateInstance(specificType, new string[] { "foo", "bar" });
Activator.CreateInstance(specificType, new object[] { values });
Now the right overload can not be found anymore.
If you add a cast you will get the expected result and the code works again:
Activator.CreateInstance(specificType, values as string[])
But i can not tell you why this happens, maybe it can be digged out of the specs.
Related Topics
How to Correctly Implement a Backgroundworker with Progressbar Updates
Passing Properties by Reference in C#
Does C# Have Extension Properties
How to Convert a Stream into a Byte[] in C#
What's the Difference Between Dynamic (C# 4) and Var
Entity Framework Async Operation Takes Ten Times as Long to Complete
Linq - Left Join, Group By, and Count
Deep Null Checking, Is There a Better Way
How to Protect My .Net Assemblies from Decompilation
Captured Closure (Loop Variable) in C# 5.0
Execute Task in Background in Wpf Application
Resolving an Ambiguous Reference
{"<User Xmlns=''> Was Not Expected.} Deserializing Twitter Xml
How to Make Sure That String Is Valid JSON Using JSON.Net
ASP.NET MVC: No Parameterless Constructor Defined for This Object
C# - "The Authentication or Decryption Has Failed." Error While Using Twitterizer in Mono