I'm making a RTS game. Every Unit in RTS game can do some actions, such as Patrol, Attack or Build. In unity, you can easily manually fill-in string
and integer
arrays for C# scripts.
Because of this, I decided that it would be easiest to have a string[] str_actions
array for ever unit and when unit is first initialised, convert this array to Action[] actions
.
I can probably do this:
string className = "Attack"
Assembly assembly = Assembly.Load("Actions");
Type t = assembly.GetType("Actions."+className);
Action action = (Action)Activator.CreateInstance(t);
But this doesn't handle two problems:
- Action doesn't have constructor that takes 0 arguments
- The possibility that
className
refers to class that is not child ofAction
How do I handle them?
So I've figured it out. I'm making it a static method
Action.fromString
. The thing I was lacking was theType.GetConstructor
method which returns theConstructorInfo
object.To answer the question as posted:
Thats ok! Using this overload of Activator.CreateInstance: MSDN you can pass an object[] in, and it will find the constructor that best fits. Having a default constructor is a good idea though, especially if you are going to utilize serialization.
You can't "handle" it in the sense that you can avoid it from happening. However, your code as written will throw an
InvalidCastException
if the cast fails. To avoid that, use theas
operator:Now
action
will just holdnull
if the cast is invalid, instead of throwing.Now for the caveat:
Activator.CreateInstance
is very rarely the right choice in C#. In general, you want to use direct instantiation or deserialization. Granted, deserialization utilizes reflection; but all the messy details are abstracted away.