2013-08-07 43 views
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; 
     } 
    } 

對於我understading,三類StatStErrDefinition,GcmStErrDefinition和CcuStErrDefinition都應該有在派生BaseClass的設置單元ID?

現在我已經定義了我的三個狀態類,我想讓它們進入註冊表。目前即時通訊使用這段代碼來嘗試獲取它們。問題是結果沒有項目。

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和特定的狀態值來獲取應在註冊表中的狀態類。 目前我的註冊表方法不起作用,因爲他無法找到任何類。所以在某個地方肯定會出錯。在此先感謝

#UPDATE 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是StatStErrDefinition類型,則StatusValue和UnitId屬性爲null。 事實是,這些成員是實例成員。有沒有辦法從他們那裏獲取價值?

+0

x.BaseType會給你眼前的繼承,而不是父母的父母,你可以在這裏閱讀 - http://msdn.microsoft .com/en-us/library/system.type.basetype.aspx –

回答

2

第一件事:你的linq查詢很長。 將其劃分在不同的步驟,並將它們存儲在differtent變量(或使propertys了出來,不管你喜歡)

這是

  1. 易於讀取/維持
  2. 易於調試

有了這個安心,我認爲你能解決你的問題:)

要檢查班級是否屬於某種類型, d使用方法。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"), 
+0

幫了很多。我已經更新了我最初的問題。 –

+0

查看更新示例 – lordkain

+0

解決方案是否正常工作,如果有請請正確回答 – lordkain

相關問題