Type thistype = stringVar.GetType();
thistype myScript = gameObject.AddComponent(stringVar);
myScript.runCustomFunction();
This doesn't work, and I believe it is because I cannot cast to a variable type if I don't know the variable type at compile time (rather than run), therefore I am unable to directly access the component I just added.
I have a gameItem class which pulls its default values from another script, then puts them into a dictionary. Based on the dictionary entry "functionScript","myScript", I need to attach myScript to the object, then pass it some dictionary entries.
Alternatively, I could be really inefficient and ask the item class for its variables on the myScript class, which I'd rather avoid.
System.Type
is an actual type, much the same as System.Int32
, or System.Guid
. You can't use a variable as a static identifier in your code since the compiler has no idea what that type is.
I think what you are trying to do is construct a concrete type based on its name.
You can use Activator.CreateInstance to do this, so long as you know the type name and assembly name.
var typeName = "MyType";
var myType = Activator.CreateInstance("MyAssembly", typeName);
You could also use the dynamic
keyword to let the DLR handle the heavy lifting for you.
dynamic myType = Activator.CreateInstance("MyAssembly", typeName);
myType.runCustomFunction();
If your type inherits from a common base type, or implements an interface, you can then cast it to that type and call your method.
//Safe cast as base type
var myType = Activator.CreateInstance("MyAssembly", typeName) as BaseType;
//Or safe cast as interface
var myType = Activator.CreateInstance("MyAssembly", typeName) as IMyType;
However, if your types do not inherit from a known type, but you know they all have a method called runCustomFunction
and you don't want to use dynamic
then you can use a little reflection to invoke that method.
//Create the System.Type using assembly qualified name
var typeName = "MyType";
var assemblyQualifiedName = String.Format("MyAssembly.{0}", typeName);
var myType = Type.GetType(assemblyQualifiedName);
//Call activator overload, but `instance` is a System.Object
var instance = Activator.CreateInstance(myType);
//Use reflection to invoke the method
myType.InvokeMember(
"runCustomFunction", //member name
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
null, //default binder
instance, //actual instance to invoke method on
null //no arguments so we use null
);
As you can see, it's much easier to just make all your types inherit from some base class or implement an interface, but you can certainly use reflection if you want to do it the hard way :)