C# 确定字节的模式

C# 确定字节的模式,c#,.net,pattern-matching,byte,bit,C#,.net,Pattern Matching,Byte,Bit,我得到一个字节,它定义了另一个值的类型 该字节称为值信息字段VIF 我有这样一份清单: private bool DefineType() { byte basicMask = 224; byte basicTimeMask = 88; byte[] powerMask = {80,72}; // 0101 0000,0100 1000 byte[] volumneFlowMask = {64,56,48};

我得到一个字节,它定义了另一个值的类型

该字节称为值信息字段VIF

我有这样一份清单:

    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!");
    }
现在我必须确定数据的类型和指数。 我的第一次尝试是这样的:

    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!");
    }
它是这样工作的,但我对这种尝试不太满意。代码不可管理,效率不高。有更好/更聪明的方法吗

// 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();
}
bool processed = false;
foreach(var checkFactory in availableFactories)
{
  if (checkFactory(VIF))
  {
     var processingFactory = processingFactories.Resolve(ItemType);
     processingFactory.Process(VIF);
     processed = true;
  }
}