2011-08-19 23 views
0

我得到一個字節,它定義了另一個值的類型。確定一個字節的模式

字節被稱爲價值信息字段(VIF)

我有一個這樣的名單:

VIF list http://img24.imageshack.us/img24/2061/viflist.jpg

現在我要確定我的數據的類型和指數。 我第一次嘗試,是這樣的:

private bool DefineType() 
    { 
     byte basicMask = 224; 
     byte basicTimeMask = 88; 
     byte[] powerMask = {80,72}; // 0101 0000,0100 1000 
     byte[] volumneFlowMask = {64,56,48}; //0100 0000, 0011 1000, 0011 0000 
     byte MassFlowMask = 40; //0010 1000 
     byte[] temperatureMask = {36, 32, 28, 24}; //0010 0100, 0010 0000, 0001 1100, 0001 1000 
     byte PressureMask = 20; // 0001 0100 
     byte AveragingDurationMask = 12; // 0000 1100 
     byte ActualityDurationMask = 8; //0000 1000 
     byte TimePointMask = 18;//0001 0010 
     byte BusAddressMask = 5; //0000 0101 
     byte ReservedMask = 16; //0001 0000 
     byte EnhancedMask = 0x06; // 0000 0110 
     byte[] ExtensionMask = {2 ,4}; //0000 0010,0000 0100 
     byte FabricationMask = 7; 

     if ((_VIF & basicMask) == 0) 
     { 
      return CheckBit(_VIF, 4) ? DefineMassVolumne() : DefineEnergy(); 
     } 

     if ((_VIF & basicTimeMask) == 0) 
     { 
      DefineTime(); 
      return true; 
     } 

     if (((_VIF & powerMask[0]) == 0) | ((_VIF & powerMask[1]) == 0)) 
     { 
      if (CheckBit(_VIF, 3)) 
      { 
       _mUnit = eUnit.W; 
       _exponent = GetExponent() - 3; 
       return true; 
      } 
      _mUnit = eUnit.J_H; 
      _exponent = GetExponent(); 
      return true; 
     } 

     if (((_VIF & volumneFlowMask[0]) == 0) | ((_VIF & volumneFlowMask[1]) == 0) | ((_VIF & volumneFlowMask[2]) == 0)) 
     { 
      DefineVolumneFlow(); 
      return true; 
     } 

     if ((_VIF & MassFlowMask) == 0) 
     { 
      _mUnit = eUnit.kg_h; 
      _exponent = GetExponent() - 3; 
      return true; 
     } 

     if (temperatureMask.Any(mask => (_VIF & mask) == 0)) 
     { 
      DefineTemperature(); return true; 
     } 

     if ((_VIF & PressureMask) == 0) 
     { 
      _mUnit = eUnit.bar; 
      _exponent = Get2DigitExponent() - 3; 
      return true; 
     } 

     if ((_VIF & AveragingDurationMask) == 0) 
     { 
      mTimeType = TimeType.AveragingDuration; 
      SetTimeRange(); 
      return true; 
     } 

     if ((_VIF & ActualityDurationMask) == 0) 
     { 
      mTimeType = TimeType.ActualityDuration; 
      SetTimeRange(); 
      return true; 
     } 

     if ((_VIF & TimePointMask) == 0) 
     { 
      mTimeType = TimeType.TimePoint; 
      if (CheckBit(_VIF, 0)) 
      { 
       _mUnit = eUnit.DateTime; 
       _exponent = 0; 
       return true; 
      } 
      _mUnit = eUnit.Date; 
      _exponent = 0; 
      return true; 
     } 

     if ((_VIF & FabricationMask) == 0) 
     { 
      _mUnit = eUnit.Fabrication; 
      _exponent = 0; 
      return true; 
     } 

     if ((_VIF & BusAddressMask) == 0) 
     { 
      _mUnit = eUnit.BusAddress; 
      _exponent = 0; 
      return true; 
     } 

     if ((_VIF & ReservedMask) == 0) 
     { 
      _mUnit = eUnit.Reserved; 
      _exponent = 0; 
      return true; 
     } 

     if ((_VIF & EnhancedMask) == 0) 
     { 
      _mUnit = eUnit.Enhanced; 
      return true; 
     } 

     foreach (Byte b in ExtensionMask) 
     { 
      if ((_VIF & b) == 0) 
      { 
       _mUnit = eUnit.Extension; 
       return true; 
      } 
     } 

     throw new Exception("VIF Code does not exist!"); 
    } 

是這樣工作的,但我不是很滿意這樣的嘗試。該代碼退出不可管理,效率不高。有更好/更聰明的方法嗎?

回答

0
// You can decouple check functions and actuall logic by 
// introducing predicate per item type, then try to figure out whether you can 
// abstract each block inside `if(predicate()) { ...here.. }` 
// into the separate factories using `Func<,>` 

// Check predicate 
Predicate<int> actualityDurationCheck = (vif) => 
             (vif & ActualityDurationMask) == 0; 

if (actualityDurationCheck(_VIF)) 
{ 
    mTimeType = TimeType.ActualityDuration; 
    SetTimeRange(); 
} 

,然後可以移動,創造某種checkFactories提供商,如:

Predicate<int> checkFactory; 
    IDictionary<ItemType, Predicate<int>> checkFactoryProvider = new ... 
    if (checkFactoryProvider.ContainsKey(ItemType.ActualityDurationMask) 
    { 
     checkFactory = checkFactoryProvider[ItemType.ActualityDurationMask]; 
    } 

    // check for nulls ets 
    if (checkFactory (_VIF)) 
    { 
     mTimeType = TimeType.ActualityDuration; 
     SetTimeRange(); 
    } 

基本上你最終會得到一些乾淨的循環像(僞)

bool processed = false; 
foreach(var checkFactory in availableFactories) 
{ 
    if (checkFactory(VIF)) 
    { 
    var processingFactory = processingFactories.Resolve(ItemType); 
    processingFactory.Process(VIF); 
    processed = true; 
    } 
} 
相關問題