簡體   English   中英

C# Activator.CreateInstance 摘要 class 找不到構造函數

[英]C# Activator.CreateInstance Abstract class can't find constructor

我試圖讓多個程序集中的命令的每個子項將它們存儲在一個列表中,但為了做到這一點,我需要創建該子項的一個實例來存儲它,但我正在嘗試使用 Activator.CreateInstance目標是讓一個 ctor 公用以供外部使用,並為 Activator 提供一個 ctor,以便它可以創建要存儲的實例,但是問題是 Activator 出於某種原因找不到 ctor,我什至將 ctor 標記為公共但沒有運氣

public abstract class Command
{
    public static List<Command> List { get; set; }
    public static Dictionary<Type, int> Lookup { get; set; }

    public Command(int id, FieldInfo[] field) 
    {
        Id = id;
        Fields = field;
    }

    public Command()
    {
        Command command = List[Lookup[GetType()]];
        Id = command.Id;
        Fields = command.Fields;
    }

    public static void Initialize()
    {
        Lookup = new Dictionary<Type, int>();
        List = new List<Command>();

        foreach (Type type in
                AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes())
                .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(Command))))
        {
            Command command = (Command)Activator.CreateInstance(type, List.Count, type.GetFields());
            Lookup.Add(type, command.Id);
            List.Add(command);
        }
    }
}

public class PlayerMove : Command
{

}

[TestClass()]
public class PacketTests
{
    [TestMethod()]
    public void PackTest()
    {
        Command.Initialize();

        Packet packet = new Packet();

        var cmd = new PlayerMove()
        {

        };

        cmd.Send(Method.Unreliable);

        var g = Command.List;
    }

我究竟做錯了什么?

您正在嘗試構建PlayerMove的實例。 這只有一個默認構造函數,即PlayerMove() ,它將調用基本構造函數Command() 因此,您對Activator.CreateInstance的調用應如下所示

Command command = (Command)Activator.CreateInstance(type);

或者,您應該向PlayerMove class 添加一個額外的構造函數:

public class PlayerMove : Command
{
    public PlayerMove(int id, FieldInfo[] field) : base(id, field){}
    public PlayerMove() : base(){}
}

但我認為你真正想要的可能是這樣的:

public abstract class Command
{
    public static List<Command> List { get; private set; }
    public static Dictionary<Type, int> Lookup { get; private set; }

    public int Id { get; }
    public FieldInfo[] Fields { get; }

    protected Command(int id, FieldInfo[] field)
    {
        Id = id;
        Fields = field;
    }

    protected Command()
    {
        Command command = List[Lookup[GetType()]];
        Id = command.Id;
        Fields = command.Fields;
    }

    public static void Initialize()
    {
        Lookup = new Dictionary<Type, int>();
        List = new List<Command>();

        foreach (Type type in
                AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes())
                .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(Command))))
        {
            Command command = (Command) Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.NonPublic, null,
                new object[] {List.Count, type.GetFields()}, null);
            Lookup.Add(type, command.Id);
            List.Add(command);
        }
    }
}

public class PlayerMove : Command
{
    private PlayerMove(int id, FieldInfo[] field) : base(id, field)
    {

    }

    public PlayerMove()
    {

    }
}

這向PlayerMove命令添加了一個私有構造函數,該命令通過反射調用並填充基礎 class 上的IdFields屬性,以及一個無參數構造函數,然后可以由 class 的其他客戶端使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM