从string创建一个类实例并调用构造函数

时间:2014-11-12 17:53:05

标签: c# reflection

我正在制作RTS游戏。 RTS游戏中的每个单元都可以执行某些操作,例如 Patrol Attack Build 。在统一中,您可以轻松地为C#脚本手动填写stringinteger数组。

正因为如此,我认为最简单的单位是string[] str_actions数组,首次初始化单位时,将此数组转换为Action[] actions

我可能do this

string className = "Attack"
Assembly assembly = Assembly.Load("Actions");
Type t = assembly.GetType("Actions."+className);
Action action = (Action)Activator.CreateInstance(t);

但这并不能解决两个问题:

  1. 动作没有带0参数的构造函数
  2. className引用不属于Action
  3. 之子的班级的可能性

    我该如何处理?

2 个答案:

答案 0 :(得分:1)

回答发布的问题:

  1. 多好啊!使用Activator.CreateInstance:MSDN的这个重载,您可以传入一个object [],它将找到最适合的构造函数。有一个默认的构造函数一个好主意,特别是如果你打算使用序列化。

  2. 你无法“处理”它,因为你可以避免它发生。但是,如果转换失败,您编写的代码将抛出InvalidCastException。为避免这种情况,请使用as运算符:

    Action action = Activator.CreateInstance(t) as Action;
    

    如果演员表无效,action将只保留null,而不是投掷。

  3. 现在请注意:Activator.CreateInstance很少是C#的正确选择。通常,您希望使用直接实例化或反序列化。当然,反序列化利用反射;但所有凌乱的细节都被抽象掉了。

答案 1 :(得分:0)

所以我已经弄明白了。我将其作为静态方法Action.fromString。我缺少的是Type.GetConstructor方法,它返回ConstructorInfo对象。

    public static Action fromString(string className, string defName, WorldObject actor)
    {
        //Get the Assembly (namespace)
        Assembly assembly = Assembly.Load("Actions");
        //Get the exact class Type
        Type t = assembly.GetType("Actions." + className);
        //Get the info about constructor (using array literal)
        // - for every accepted parameter enter typeof(parameterType)
        ConstructorInfo constructor = t.GetConstructor(new Type[] { typeof(string), typeof(WorldObject) });
        //Initialise the Type instance
        System.Object action = constructor.Invoke(new System.Object[] { defName, actor });
        //If it's child of the main class
        if (action is Action)
            return (Action)action;
        //Error otherwise
        else
        {
            Debug.LogError("'" + className + "' is not child of Action!");
            return null;
        }
    }