查找从特定基类派生的所有类,并将它们添加到注册表中
本文关键字:添加 注册表 基类 派生 查找 | 更新日期: 2023-09-27 18:26:38
我有一个名为BaseStatus的基类,它看起来像这样:
public class BaseStatus
{
public int UnitId { get; protected set; }
public UInt16 StatusValue { get; protected set; }
public string StatusCode { get; protected set; }
public string StatusDescription { get; protected set; }
public BaseStatus()
{
this.UnitId = -1;
this.StatusValue = 0;
this.StatusCode = null;
this.StatusDescription = null;
}
}
此外,我有两个或多个其他基类,它们从BaseStatus派生并定义其他单元id。例如,这两个类
public class BaseGlobalStatus : BaseStatus
{
public BaseGlobalStatus()
{
base.UnitId = -1;
}
}
public class BaseGcmGdmStatus : BaseStatus
{
public BaseGcmGdmStatus()
{
base.UnitId = 2;
}
}
public class BaseCcuStatus : BaseStatus
{
public BaseCcuStatus()
{
base.UnitId = 1;
}
}
背景是,我想从例如BaseCcuStatus派生,并在派生类中具有正确的UnitId。
现在我定义了正确的状态类,例如:
public class StatStErrDefinition : BaseGlobalStatus
{
public StatStErrDefinition()
: base()
{
base.StatusDescription = "Kommando nicht zulässig, unit im state ERROR";
base.StatusCode = "STAT_ST_ERR";
base.StatusValue = 3;
}
}
public class GcmStErrDefinition : BaseGcmGdmStatus
{
public GcmStErrDefinition()
: base()
{
base.StatusDescription = "Kommando nicht zulässig, unit im state ERROR";
base.StatusCode = "STAT_ST_ERR";
base.StatusValue = 3;
}
}
public class CcuStErrDefinition : BaseCcuStatus
{
public CcuStErrDefinition()
: base()
{
base.StatusDescription = "Kommando nicht zulässig, unit im state ERROR";
base.StatusCode = "STAT_ST_ERR";
base.StatusValue = 3;
}
}
据我所知,StatStErrDefinition、GcmStErrDefinition和CcuStErrDefine这三个类应该具有在派生基类中设置的UnitId?
既然我已经定义了我的三个状态类,我想把它们放到注册表中。目前我正在使用这段代码来尝试获取它们。问题是结果中没有项目。
registry = new StatusDictionary<UInt16, BaseStatus>();
var unitStatus = typeof(BaseStatus)
.Assembly.GetTypes()
.Where(x => x.BaseType == typeof(BaseStatus))
.Select(x => new
{
StatusType = x,
UnitId = x.GetProperty("UnitId", BindingFlags.Public)
StatVal = x.GetProperty("StatusValue", BindingFlags.Public)
}
)
.Where(x => x.StatVal != null && x.UnitId != null)
.Select(x => new
{
UnitId = (int)x.UnitId.GetValue(null, null),
StatusValue = (UInt16)x.StatVal.GetValue(null, null),
Factory = (Func<BaseStatus>)(() => ((BaseStatus)Activator.CreateInstance(x.StatusType)))
});
try
{
foreach (var status in unitStatus)
{
if (status.UnitId == unitId
|| status.UnitId < 0)
registry.Register(status.StatusValue, status.Factory);
}
}
catch (Exception ex)
{
string temp = ex.Message;
}
在LINQ表达式之后,var unitStatus为空。。。
稍后,注册表调用看起来像这样来获取特定的类,但在这一点上并不重要:
stat = StatusContainer.GetRegistry(this.unitTypeId).GetInstance(this.StatusValue);
供参考:我想通过unittypeid和特定的状态值获得应该在注册表中的状态类。目前我的注册表方法不起作用,因为他找不到任何类。所以一定是哪里出了错。提前感谢
#更新1
我稍微改变了一下我的功能:
registry = new StatusDictionary<UInt16, BaseStatus>();
//get all types of cucrent assembly
var allAssemblyTypes = Assembly.GetCallingAssembly().GetTypes();
//get all types from base status
var baseStatusTypes = allAssemblyTypes.Where(x => x.BaseType == typeof(BaseStatus));
//Place all concrete types in the foundtypes
List<Type> foundTypes = new List<Type>();
foreach (Type item in baseStatusTypes)
{
var temp = allAssemblyTypes.Where(x => x.BaseType == item)
.Select(x => new
{
StatusType = x,
UnitId = x.GetProperty("UnitId", BindingFlags.Public),
StatVal = x.GetProperty("StatusValue", BindingFlags.Public),
}
);
}
Temp现在包含正确的类型。问题是,如果temp是StatStErrDefinition类型,则StatusValue和UnitId属性为null。事实上,这些成员都是实例成员。有没有办法让它们发挥价值?
首先,您的LINQ查询相当长。将其分为不同的步骤,并将其存储在不同的变量中(或者用它们创建属性,无论你喜欢什么)
这是
- 易于阅读/维护
- 易于调试
有了这个,我认为你能够解决你的问题:)
要检查类是否为特定类型,可以使用方法.OfType
使用此方法获取值。请注意,您必须在您的案例中创建一个实例,因为构造函数中的值发生了更改。
public static object GetPropValue(Type src, string propName)
{
var prop = src.GetProperty(propName);
var instance = Activator.CreateInstance(src);
var value = prop.GetValue(instance);
return value;
}
代替
UnitId = x.GetProperty("UnitId", BindingFlags.Public),
使用
UnitId = GetPropValue(x,"UnitId"),