C# 如何创建模块化类列表属性

C# 如何创建模块化类列表属性,c#,class,unity3d,modular-design,C#,Class,Unity3d,Modular Design,我可能问错了问题,因为我在网上找不到关于这个的任何东西 本质上,我的目标是在project\Schemas\move.cs中定义一个move类: public class Move { private int power; private float accuracy; private string type; private string style; public Move(int p, float a, string t, string s,

我可能问错了问题,因为我在网上找不到关于这个的任何东西

本质上,我的目标是在project\Schemas\move.cs中定义一个move类:

public class Move
{
    private int power;
    private float accuracy;
    private string type; 
    private string style; 

    public Move(int p, float a, string t, string s, float sh)
    {
        this.power = p;
        this.accuracy = a;
        this.type = t;
        this.style = s;
    }

}
我希望可以从我的游戏引擎访问所有移动的集合,但我希望该移动集合能够基于project\moves\move.*下的其他文件自动生成

老实说,我不知道如何在C#中这样做。在另一种语言中,我只需初始化一个全局集合,并在每个移动文件中调用
GlobalCollection.Add(newmove(…)
或类似的东西

希望有人能帮我

没有(好的)方法来做你想做的事。

备选案文1: 你自己亲手写出来。例如。这将始终有效,并且是您试图避免的事情

备选案文2:
反射性地检查程序集并加载它包含的所有类。但这很容易发生意想不到的事情。例如,在创建独立构建时,Unity会从编译中剔除这些类,因为它们没有在任何地方引用。或者无意中实例化了一个不应该出现的对象。或者忘记了“哦,是的,MoveXYZ有一个唯一的构造函数,需要一个额外的参数。”

如果我理解正确,您尝试的是拥有一个,例如
列表
,您希望在这里“注册”每个创建的
Move
实例。那么,为什么不简单地说

// This is a static class so it does not have to be instantiated
// but rather simply "lives" in the assets
public static class MoveManager
{
    public static List<Move> Moves = new List<Move>();
}
public class Move
{
    private int power;
    private float accuracy;
    private string type; 
    private string style;  

    public Move(int p, float a, string t, string s, float sh)
    {
        power = p;
        accuracy = a;
        type = t;
        style = s;

        // a static class member is simply accessed via the type itself
        MoveManager.Moves.Add(this);
    }
}
问题:什么时候从列表中删除它们?

通常,您希望在解构器中执行此操作,例如

~Move()
{
    MoveManager.Moves.Remove(this);
}

但是在Unity中解构器不会自动调用-尤其是当任何东西仍在引用此
移动
实例时。。。扰流板警报:
移动
列表将始终有效!因此,如果需要,您必须在每次确实要销毁
移动
实例时“手动”清理
移动
列表。

添加derHugo给出的答案,以防其他人意外发现。我正在使用建议的方法,但发现为了在运行时“导入”类型,必须使用
[RuntimeInitializeOnLoadMethod]
。可能还有其他的方法,但这里有3个移动文件,我最终得到的答案完成的采取

MoveManager.cs

move_basic.cs

下一步,既然我已经确认了这一点,那么将向注册的移动添加方法,这才是真正的魔力所在

当您需要创建一个易于扩展的对象库(可能需要包含可调用的方法)时,这似乎是一个非常理想的解决方案。如果不是出于这种需要,从csv或其他文件导入属性可能会更好


一般来说,我对unity和游戏设计非常陌生,因此我非常高兴编辑/更正/改进这篇文章,以帮助未来的搜索者。

为什么你不能在C#中也这样做?我的意思是,为了初始化全局集合,您需要事先知道可能的移动列表(在
project\moves\move.*
中(PS:C中的名称
move.
有点奇怪)因为在C#中,编译器不会接受在命名空间或类之外运行的函数,我希望避免将每一项作为类导入/初始化……我不会死气沉沉地使用move#或任何命名方案,主要目标是使父文件夹中的所有内容动态加载到gl中有意思的是,这让我有点思考和研究……这两个选项似乎都不是特别吸引人的,但我想如果它们是唯一的方法,那么这就是筹码下降的原因。我会继续寻找一点,如果我最终使用其中一个,我会接受答案。太棒了,这是真实的ly看起来正是我要找的!不需要从这个列表中删除移动,因为它将是全球注册商…谢谢@derHugo!
 public static class MoveManager
 {
    public static List<Move> Moves = new List<Move>();
 }
public class Move
{
    public string name;
    public string description;
    public Target target;
    public int power;
    public float accuracy;
    public int cost;
    public game_Type type;
    public Style style;

    public Move(
        string name
        , string description
        , int power
        , float accuracy
        , int cost
        , string typeName
        , string styleName
        , string targetType
    )
    {
        this.name = name;
        this.power = power;
        this.accuracy = accuracy;
        this.description = description;

        this.type = game_Types.getByName(typeName);
        this.style = MasterStyles.getByName(styleName);
        this.target = new Target(targetType);

        // a static class member is simply accessed via the type itself
        Debug.Log("Registering " + name + " type!");
        MoveManager.Moves.Add(this);
    }
}
class move_basic
{
    [RuntimeInitializeOnLoadMethod]
    static void OnRuntimeMethodLoad()
    {
        // Name this move
        string name = "Attack!";
        // Describe this move
        string description = "Strike out at the enemy with tooth, claw, weapon, or whatever else is available!";
        // Choose the type of target this move is for
        // self/ally/selfAlly/enemy/enemies
        string target = "enemy";
        // The move typing - This determines cost reduction as well as potential attack bonuses
        string typeName = "physical";
        game_Type type = game_Types.Types.Find(x => x.name == typeName);
        // The move style - This determines additional bonuses and modifiers
        string styleName = "martial";
        // Style style = ??
        // Power of the move, base/'normal' power is 50.
        int power = 50;
        // Accuracy of the move, base/normal is 90
        int accuracy = 90;
        // MP Cost of the move
        int cost = 0;


        Move mv = new Move(name, description, power, accuracy, cost, typeName, styleName, target);
    }
}