Ограничить строковое свойство заранее заданным набором значений (обходной путь без дефисов в перечислении) - PullRequest
2 голосов
/ 24 февраля 2010

У меня есть строковое свойство, которое я хотел бы иметь с помощью двух вещей: - Он может быть установлен только на определенные значения в заранее определенном списке, - Проверка ошибок значения свойства может быть выполнена во время компиляции.

Перечисление отлично подходит для счета, за исключением того, что в моем списке предопределенных строк есть строка с дефисом, а значения перечисления не могут содержать дефисы . Чтобы проиллюстрировать идеальное решение, если перечисление может содержать дефисы, я бы создал перечисление:

public enum SIPEventPackagesEnum
{
    dialog,
    message-summary,
    refer
}

Для использования:

SIPEventPackagesEnum EventPackage = SIPEventPackagesEnum.message-summary;

Для установки:

string eventPackageStr = "message-summary";
SIPEventPackagesEnum EventPackage = (SIPEventPackagesEnum)Enum.Parse(typeof(SIPEventPackagesEnum), eventPackageStr, true);

В вышеупомянутых случаях невозможно установить для свойства EventPackage что-либо, кроме одного из значений перечисления, и его использование интуитивно понятно, поскольку intellisense перечислит доступные параметры.

Из-за невозможности использования дефиса, и я не могу изменить предопределенный список, чтобы удалить дефис, очень грубый подход состоит в том, чтобы использовать структуру и иметь свойство «Значение» в структуре, которое выполняет принудительное выполнение в его установщик, см. ниже. Это очень многословно по сравнению с использованием enum, а также не позволяет проверять время компиляции и не очень интуитивно понятно.

Кто-нибудь сталкивался с этой проблемой раньше и есть лучшее решение? У меня есть несколько списков с элементами, содержащими дефисы, так что это не один раз.

public struct SIPEventPackages
{
    public const string DIALOG = "dialog";                   
    public const string MESSAGE_SUMMARY = "message-summary";   
    public const string REFER = "refer";                      

    public string Value
    {
        get { return Value; }
        set
        {
            if (IsValid(value))
            {
                Value = value.ToLower();
            }
            else
            {
                throw new ArgumentException(value + " is invalid for a SIP event package.");
            }
        }
    }

    public bool IsValid(string value)
    {
        if (value.IsNullOrBlank())
        {
            return false;
        }
        else if (value.ToLower() == DIALOG || value.ToLower() == MESSAGE_SUMMARY || value.ToLower() == REFER)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public override string ToString()
    {
        return Value;
    }
}

Ответы [ 3 ]

0 голосов
/ 24 февраля 2010

Вы можете создать перечисление без -, затем иметь статический Dictionary<SIPEventPackagesEnum ,string> в классе помощника, отображающем значение из перечисления в строку для преобразования из перечисления в строку, а затем использовать Enum.Parse(typeof(SIPEventPackagesEnum), str.Replace("-", "")) при преобразовании из строки в перечисление.

Или используйте _ вместо - и заменяйте _ на - и наоборот при необходимости

Или используйте верблюжий регистр в значениях перечисления и замените заглавную букву в имени перечисления на «- <строчная буква>» с помощью регулярного выражения

0 голосов
/ 25 февраля 2010

Мне удалось отрегулировать мой подход так, чтобы он был почти таким же хорошим, как enum, хотя и требовал гораздо большего количества кода. Это стоит того, чтобы использовать сантехнический код, чтобы сохранить потенциальные проблемы с ошибками в будущем.

public struct SIPEventPackage
{
    public static SIPEventPackage None = new SIPEventPackage(null);
    public static SIPEventPackage Dialog = new SIPEventPackage("dialog");                   
    public static SIPEventPackage MessageSummary = new SIPEventPackage("message-summary"); 
    public static SIPEventPackage Refer = new SIPEventPackage("refer");                    

    private string m_value;

    private SIPEventPackage(string value)
    {
        m_value = value;
    }

    public override string ToString()
    {
        return m_value;
    }

    public static SIPEventPackage Parse(string value)
    {
        if (!IsValid(value))
        {
            throw new ArgumentException("The value is not valid for a SIPEventPackage.");
        }
        else
        {
            string trimmedValue = value.Trim().ToLower();
            switch (trimmedValue)
            {
                case "dialog": return SIPEventPackage.Dialog;
                case "message-summary": return SIPEventPackage.MessageSummary;
                case "refer": return SIPEventPackage.Refer;
                default: throw new ArgumentException("The value is not valid for a SIPEventPackage.");
            }
        }
    }
}

Требуется немного больше сантехники, реализуя метод и оператор IsValid == и еще несколько, но главное, что теперь я могу использовать структуру практически идентично перечислению и иметь элементы с дефисами.

0 голосов
/ 24 февраля 2010

Кажется, это просто с помощью делегата

        Func<string, bool> isValid = str =>
        {
            List<string> validLst = new List<string>() { "dialog","message-summary","refer" };
            if (validLst.Find(x => string.Equals(x,str,StringComparison.InvariantCultureIgnoreCase)) == null)
                return false;
            return true;

        };

        var teststr1 = "message-summary";
        var teststr2 = "wrongone";
        isValid(teststr1);
        isValid(teststr2);

Uptdate:

В противном случае вы можете использовать подход enum немного по-другому. Иметь значение перечисления без дефиса. И просто удалите дефисы из исходной строки при разборе значений перечисления. это будет работать, как вы ожидали

    public enum SIPEventPackagesEnum
    {
        dialog,
        messagesummary,
        refer
    }

    string eventPackageStr = "message-summary";
    SIPEventPackagesEnum EventPackage = (SIPEventPackagesEnum)Enum.Parse(typeof(SIPEventPackagesEnum), eventPackageStr.Replace("-",""), true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...