1

我有一个名为 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 和 CcuStErrDefinition 应该具有在派生 BaseClass 中设置的 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 属性为空。事实上,这些成员是实例成员。有没有办法从中获取价值?

4

1 回答 1

2

首先第一件事:您的 linq 查询很长。将其划分为不同的步骤并将它们存储在不同的变量中(或从它们中创建属性,无论您喜欢什么)

这是

  1. 易于阅读/维护
  2. 易于调试

有了这个 givin,我认为您能够解决您的问题 :)

要检查该类是否属于某种类型,您可以使用方法.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"),
于 2013-08-07T06:17:37.030 回答