C# - 通过构造函数自动初始化 class 的字段(手动与动态)
C# - Auto-initialization of class's fields via the constructor (manual vs dynamic)
我偶然发现了一个案例,它不影响我的设计,但很可能会影响未来代码和性能的变化。
我的class如下:
public sealed class Commands {
public interface ICommand {
string commandName { get; set; }
}
public ICommand Maintain;
public ICommand Dispatch;
public ICommand Memorize;
//............//
private class ReckonCommand : ICommand {
public string commandName { get; set; }
public ReckonCommand (string name) {
this.commandName = name;
}
}
public Commands () {
Maintain = new ReckonCommand ("Maintain") as ICommand;
Dispatch = new ReckonCommand ("Dispatch") as ICommand;
Memorize = new ReckonCommand ("Memorize") as ICommand;
}
此方法需要手动初始化命令 class 中的每个 ICommand 变量。因此,当字段变多时,将变得难以维护。
另一种动态方法如下:
public ICommand Maintain;
public ICommand Dispatch;
public ICommand Memorize;
//............//
private class ReckonCommand : ICommand {
public float commandName { get; set; }
//Stuff
}
public Commands () {
System.Reflection.FieldInfo[] _fields = GetType ().GetFields ();
for (int i = 0; i < _fields.Length; i++) {
if (_fields [i].FieldType == typeof(ICommand)) {
_fields [i].SetValue (this, new ReckonCommand () as ICommand);
}
}
}
然而,命令 class 预计会被初始化多次(忽略名称,如果这会妨碍您理解),因此性能损失可能会在某些时候产生影响。
我正在使用的这个特定设计是否有替代方案?我关心的是在 Commands 的构造函数中自动初始化每个 ICommand 字段 class.The 手动方法容易出错,当发现时可能为时已晚。
动态方法是完全可以接受的(我们一直在大规模应用程序中使用它来解决您所描述的问题)。
但是,您应该在 class 的静态构造函数中实现发现并将结果存储在静态集合中,这样您就不必在每次 [= 的实例时都执行反射17=] 已创建。
大致如下:
private static System.Collections.Generic.List<System.Reflection.FieldInfo> _fields;
static Commands()
{
_fields = new System.Collections.Generic.List<System.Reflection.FieldInfo>();
var fields = typeof(Commands).GetFields();
var commandType = typeof(ICommand);
foreach (var field in fields)
{
if (field.FieldType == commandType)
{
_fields.Add(field);
}
}
}
public Commands()
{
foreach (var field in _fields)
{
field.SetValue(this, new ReckonCommand() as ICommand);
}
}
我偶然发现了一个案例,它不影响我的设计,但很可能会影响未来代码和性能的变化。
我的class如下:
public sealed class Commands {
public interface ICommand {
string commandName { get; set; }
}
public ICommand Maintain;
public ICommand Dispatch;
public ICommand Memorize;
//............//
private class ReckonCommand : ICommand {
public string commandName { get; set; }
public ReckonCommand (string name) {
this.commandName = name;
}
}
public Commands () {
Maintain = new ReckonCommand ("Maintain") as ICommand;
Dispatch = new ReckonCommand ("Dispatch") as ICommand;
Memorize = new ReckonCommand ("Memorize") as ICommand;
}
此方法需要手动初始化命令 class 中的每个 ICommand 变量。因此,当字段变多时,将变得难以维护。
另一种动态方法如下:
public ICommand Maintain;
public ICommand Dispatch;
public ICommand Memorize;
//............//
private class ReckonCommand : ICommand {
public float commandName { get; set; }
//Stuff
}
public Commands () {
System.Reflection.FieldInfo[] _fields = GetType ().GetFields ();
for (int i = 0; i < _fields.Length; i++) {
if (_fields [i].FieldType == typeof(ICommand)) {
_fields [i].SetValue (this, new ReckonCommand () as ICommand);
}
}
}
然而,命令 class 预计会被初始化多次(忽略名称,如果这会妨碍您理解),因此性能损失可能会在某些时候产生影响。
我正在使用的这个特定设计是否有替代方案?我关心的是在 Commands 的构造函数中自动初始化每个 ICommand 字段 class.The 手动方法容易出错,当发现时可能为时已晚。
动态方法是完全可以接受的(我们一直在大规模应用程序中使用它来解决您所描述的问题)。
但是,您应该在 class 的静态构造函数中实现发现并将结果存储在静态集合中,这样您就不必在每次 [= 的实例时都执行反射17=] 已创建。
大致如下:
private static System.Collections.Generic.List<System.Reflection.FieldInfo> _fields;
static Commands()
{
_fields = new System.Collections.Generic.List<System.Reflection.FieldInfo>();
var fields = typeof(Commands).GetFields();
var commandType = typeof(ICommand);
foreach (var field in fields)
{
if (field.FieldType == commandType)
{
_fields.Add(field);
}
}
}
public Commands()
{
foreach (var field in _fields)
{
field.SetValue(this, new ReckonCommand() as ICommand);
}
}