从字符串中解析代码符号以构建枚举数组的有效方法

问题描述 投票:-1回答:3

我从远程设备获取数据,该设备发送包含单字母代码的状态字符串的数字数据。我需要将字符串中的所有单字符状态代码映射到相应的枚举值,并将这些枚举值放入属性中,然后类消费者可以调用该属性来理解状态,而无需查找单字符状态代码。示例状态字符串是“...... Q.D..B”。

是否有一种模式可以在不使用巨大的switch语句或多个if语句的情况下执行此操作?

注意:代码实际上包含超过20种状态,但为了简洁起见,我将其编辑出来。

[Flags]
public enum DataQuality
{
    Good = 0x0001,                           
    Questionable = 0x0004,                  
    NotCorrected = 0x0008,             
    BadEstimatedValue = 0x0010        
}

public class DataPointStatus
{
    private const string Good = "...";
    private const char Questionable = 'Q';
    private const char NotCorrected = 'D';
    private const char BadEstimatedValue = 'B';
    // Lot's more statuses...

    private readonly string _rawStatus;
    private readonly List<DataQuality> _statuses = new List<DataQuality>();

    public DataPointStatus(string rawStatus)
    {
        if (rawStatus == null)
        {
            throw new ArgumentNullException($"'{nameof(rawStatus)}' cannot be null.");
        }

        if (rawStatus.Trim() == string.Empty)
        {
            throw new ArgumentException($"'{nameof(rawStatus)}' cannot be an empty string.");
        }

        _rawStatus = rawStatus;

        SetStatusToGoodIfDataHasNoQualityErrors();
        if (!IsGood) SetBadQualityStatuses();
    }

    public bool IsGood => _statuses.Any(x => x == DataQuality.Good);
    public IEnumerable<DataQuality> Statuses => _statuses;

    private void CheckForGoodStatus()
    {
        if (_rawStatus == Good)
        {
            _statuses.Add(DataQuality.Good);
        }
    }

    private void SetStatusToGoodIfDataHasNoQualityErrors()
    {
        string status = _rawStatus.Replace(".", string.Empty);

        Start:
        switch (status)
        {
            case string s when s == "": return;

            case string s when s.Contains(Questionable):
                _statuses.Add(DataQuality.Questionable);
                status = status.Trim(Questionable);
                goto Start;

            case string s when s.Contains(NotCorrected):
                _statuses.Add(DataQuality.NotCorrected);
                status = status.Trim(NotCorrected);
                goto Start;

            case string s when s.Contains(BadEstimatedValue):
                _statuses.Add(DataQuality.BadEstimatedValue);
                status = status.Trim(BadEstimatedValue);
                goto Start;

            default:
                throw new ArgumentOutOfRangeException(
                    $"Invalid status code.");
        }
    }
}
c# enums
3个回答
1
投票

您可以使用正则表达式来查找状态

//Regular expression can be more elaborated, 
//searching the status char in a concrete part of the string and so on
Regex regex = new Regex("Q|D|B"); 

然后是一个字典,用于将字符串值与相应的标志值进行匹配

Dictionary<string, DataQuality> qualities = InitializeDictionary();

这应该放在一个循环中。像qazxsw poi这样的东西:

while (rawStatus != "")

1
投票

你可以在字典中存储枚举:

Match match = regex.Match(rawStatus);
if (match.Success) {
    _statuses.Add(qualities[match.Value]);
    rawStatus = regex.Replace(rawStatus, "");
}

1
投票

这不会直接适用于您的代码,因为您需要Flag。 要将字符串解析为Enum Value列表,可以使用char Enum:

var dic = new Dictionary<string, DataQuality>(StringComparer.OrdinalIgnoreCase)
{
    ["G"] = DataQuality.Good,
    ["Q"] = DataQuality.Questionable,
    ["N"] = DataQuality.NotCorrected,
    ["B"] = DataQuality.BadEstimatedValue
};
string input = "Q";
if (dic.TryGetValue(input, out var status))
{
    // Use "status" variable here
}

您可以使用Enum MyEnum { Good = 'g', Questionable = 'q', NotCorrected = 'n', BadEstimatedValue = 'b' //[...] } Enum.TryParse将字符串转换为其枚举值。 但对于一个炭,一个简单的演员Parse是应该的。 这会将所有char转换为int值,即使它们未在枚举中定义。 (MyEnum)myChar将指出它是否存在于指定的枚举中。

对于char enum:

Enum.IsDefined

结果:

可疑的 NotCorrected 好 BadEstimatedValue 可疑的 NotCorrected 好

© www.soinside.com 2019 - 2024. All rights reserved.