[英]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 上的Id
和Fields
屬性,以及一個無參數構造函數,然后可以由 class 的其他客戶端使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.