How to Pass Parameters to Activator.CreateInstanceT()
Yes.
(T)Activator.CreateInstance(typeof(T), param1, param2);
Activator.CreateInstance pass variable to form
You should cast to Form2
, not to Form
.
I don't know where is problem (if you cast to correct type), but if you have corresponding constructor, your code works fine for me.
You can try to pass arguments as object[]
(object
array) - CreateInstance(Type type, object[] args), but also you can pass arguments by the way you pass them (because method accepts params object[] args
).
Try to replace this line:
var obj = (Form)Activator.CreateInstance(Type.GetType("myproject.Form2"),1,"test");
by this:
var obj =
(Form2)Activator.CreateInstance(Type.GetType("myproject.Form2"), new object[] {1, "test"});
Also, you can use typeof
to get Type
instance:
var obj = (Form2)Activator.CreateInstance(typeof(Form2), new object[] {1, "test"});
But if you know which type of instance to create at compile time, you should simply create your object using new
:
var obj = new Form2(1, "test");
How can I use Activator.CreateInstance to create a ListT where T is unknown at runtime?
Use this approach:
class Program
{
static void Main(string[] args)
{
CreateListFromType(typeof(Foo));
CreateListFromType(typeof(int));
}
static object CreateListFromType(Type t)
{
// Create an array of the required type
Array values = Array.CreateInstance(t, 50);
// and fill it with values of the required type
for (int i = 0; i < 50; i++)
{
values.SetValue(CreateFooFromType(t), i);
}
// Create a list of the required type, passing the values to the constructor
Type genericListType = typeof(List<>);
Type concreteListType = genericListType.MakeGenericType(t);
object list = Activator.CreateInstance(concreteListType, new object[] { values });
// DO something with list which is now an List<t> filled with 50 ts
return list;
}
// Create a value of the required type
static object CreateFooFromType(Type t)
{
return Activator.CreateInstance(t);
}
}
class Foo
{
public Foo() { }
}
There is no need to use dynamic
in this case. We can just use object
for the value we create. Non-Reference types will be stored in the object
using boxing.
In order to create the List<>
type, we can first get a representation of the generic type and then use that to create the concrete type using the MakeGenericType
method.
Note the mistake you made in the CreateInstance call to create the list:
When trying to construct the list, you need to embed your values array as an element in an array of object. So that Activator
will look for a constructor in List<t>
that expects a single parameter of type IEnumerable<t>
.
The way you have written it, the Activator
looks for a constructor which expects 50 arguments, each of type t.
A shorter version using non-generic IList interface
using System.Collections;
static IList CreateListFromType(Type t)
{
// Create a list of the required type and cast to IList
Type genericListType = typeof(List<>);
Type concreteListType = genericListType.MakeGenericType(t);
IList list = Activator.CreateInstance(concreteListType) as IList;
// Add values
for (int i = 0; i < 50; i++)
{
list.Add(CreateFooFromType(t));
}
// DO something with list which is now an List<t> filled with 50 ts
return list;
}
Getting closer to the actual use case: Dynamic List Type
static void Main(string[] args)
{
CreateListFromType(typeof(List<Foo>));
CreateListFromType(typeof(ObservableCollection<int>));
}
static IList CreateListFromType(Type listType)
{
// Check we have a type that implements IList
Type iListType = typeof(IList);
if (!listType.GetInterfaces().Contains(iListType))
{
throw new ArgumentException("No IList", nameof(listType));
}
// Check we have a a generic type parameter and get it
Type elementType = listType.GenericTypeArguments.FirstOrDefault();
if (elementType == null)
{
throw new ArgumentException("No Element Type", nameof(listType));
}
// Create a list of the required type and cast to IList
IList list = Activator.CreateInstance(listType) as IList;
// Add values
for (int i = 0; i < 50; i++)
{
list.Add(CreateFooFromType(elementType));
}
// DO something with list which is now a filled object of type listType
return list;
}
Activator.CreateInstance with param - constructor of child class type not found
Activator.CreateInstance takes a nonPublic
parameter only in the case of default constructor invocation.
You can use Type.GetConstructor instead:
Type contextFactoryType =
Type.GetType("Media.DB.Context.Implementation." + Settings.ContextFactory);
ConstructorInfo ci = contextFactoryType .GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
binder: null, new Type[] { typeof(string) }, modifiers: null);
object[] args = new object[] { connString };
var instance = (BaseContext<DbContext> instance)ci.Invoke(args);
return instance;
Pass arguments as well as string into Activator.CreateInstance
Just pass them in as the 2nd argument.
IFile file = (IFile)Activator.CreateInstance(
Type.GetType("FileParser.File" + args[0]), new object[] { args });
EDIT: Wrapped the 2nd argument in an array as this is the parameter type expected, as well as the argument type on Activator.CreateInstance
, I think this is why it is confusing.
Why is Activator.CreateInstanceT() allowed without the new() generic type constraint?
There is a conceptual difference between Activator
and T()
:
Activator.CreateInstance<T>
— I want to create a new instance ofT
using its default constructor — And throw anException
if it doesn't have one (Since something very wrong has happened and I want to handle it/throw it myself).Side note: keep in mind that as MSDN says:
In general, there is no use for the
CreateInstance<T>()
generic method in application code, because the type must be known at compile time. If the type is known at compile time, normal instantiation syntax can be used.since generally you would want to use a constructor when the
Type
is known at compile time (CreateInstance<T>()
usesRuntimeTypeHandle.CreateInstance
which is slower [Also that's whyActivator.CreateInstance<T>
itself doesn't need the constraint]).
T()
— I Want to call the empty constructor ofT
, supposedly like a standard constructor call.
You don't want a "standard" constructor call to fail because "No such constructor was found", therefore, the compiler wants you to constraint that there is one.
More than that; You should prefer Compile time errors over Exceptions
where possible.
The fact that T()
is implemented internally using reflection irrelevant for the average case of "I just want a default instance of T
" (of course that the internal implementation is important if you care about performance/etc...).
Activator.CreateInstance with dynamic Type
There are a using difference... When you write:
var obj = Activator.CreateInstance<myType>();
You used your Class like a Type, and it's the good way to do it.
You used a generic type who have a reference to a class type.
But there:
var obj2 =(myType) Activator.CreateInstance(myType);
You used you class like an instance (object). And you can't do that, a class is a schema.
If you want to call the second method, you have to write:
var obj2 =(myType) Activator.CreateInstance(typeof(myType));
This code will create an instance of the class Type, and this instance will describe your class myType.
I hope to be clear.
A class is a schema, you can create an object with this schema, it will be an instance (a memory-object of your class).
Can't Find Constructor on Generic Class Activator
Activator.CreateInstance()
only looks for public constructors by default. If you want to look for other scopes of constructor, you need to use the overload with BindingFlags
.
The flags needed are:
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
You probably also want to use InvariantCulture
, so the overall call would look something like:
return Activator.CreateInstance(type, flags, null, new object[] {myArgs}, CultureInfo.InvariantCulture;)
Related Topics
Curiously Recurring Template Pattern and Generics Constraints (C#)
Windows Forms Graphic Issue on Windows 10 Os
Garbage Collection When Using Anonymous Delegates for Event Handling
Redirecting Output to the Text File C#
Why Can't I Declare C# Methods Virtual and Static
How to Implement Automatic Sorting of Datagridview
Does Using Parameterized SQLcommand Make My Program Immune to SQL Injection
Mvvm Light & Wpf - Binding Multiple Instances of a Window to a Viewmodel
How to Send a File and Form Data with Httpclient in C#
How to Take the Cartesian Join of Two Lists in C#
How to Turn Off Impersonation Just in a Couple Instances
Newtonsoft JSON.Net Serialize Jobject Doesn't Ignore Nulls, Even with the Right Settings
Xdocument: Saving Xml to File Without Bom
Get the Default Timezone for a Country (Via Cultureinfo)
Can the Oracle Managed Driver Use Async/Await Properly
How to Create a Real-Time Excel Automation Add-In in C# Using Rtdserver