Как определить перечисление со строковым значением?


Я пытаюсь определить Enum и добавить допустимые общие разделители, которые используются в CSV или подобных файлов. Тогда я собираюсь привязать его к ComboBox как источник данных, поэтому всякий раз, когда я добавляю или удаляю из определения перечисления, мне не нужно ничего менять в поле со списком.

проблема в том, как я могу определить перечисление со строковым представлением, что-то вроде:

public enum SeparatorChars{Comma = ",", Tab = "t", Space = " "}

12 63

12 ответов:

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

enum Separator
{
    Comma = ',',
    Tab = '\t',
    Space = ' '
}

(EDIT: просто чтобы уточнить, вы не можете сделать char базовый тип enum, но вы можете использовать char константы для присвоения интегрального значения, соответствующего каждому значению перечисления. Базовый тип вышеуказанного перечисления является int.)

затем метод расширения, если он вам нужен:

public string ToSeparatorString(this Separator separator)
{
    // TODO: validation
    return ((char) separator).ToString();
}

насколько я знаю, вам не будет разрешено присваивать строковые значения перечислению. То, что вы можете сделать, это создать класс со строковыми константами в нем.

public static class SeparatorChars
{
    public static String Comma { get { return ",";} } 
    public static String Tab { get { return "\t,";} } 
    public static String Space { get { return " ";} } 
}

вы можете достичь этого, но потребуется немного работы.

  1. определите класс атрибутов, который будет содержать строковое значение для enum.
  2. определите метод расширения, который вернет значение из атрибута. Например..GetStringValue (это значение перечисления) возвращает значение атрибута.
  3. тогда вы можете определить перечисление следующим образом..
public enum Test : int {
    [StringValue("a")]
    Foo = 1,
    [StringValue("b")]
    Something = 2        
} 
  1. чтобы вернуть значение из Attrinbute Тест.Foo.GetStringValue();

относятся : Перечисление Со Строковыми Значениями В C#

вы не можете сделать это с перечислениями, но вы можете сделать это так:

public static class SeparatorChars
{
    public static string Comma = ",";

    public static string Tab = "\t";

    public static string Space = " ";
}

для простого перечисления строковых значений (или любого другого типа):

public static class MyEnumClass
{
    public const string 
        MyValue1 = "My value 1",
        MyValue2 = "My value 2";
}

использование: string MyValue = MyEnumClass.MyValue1;

вы не можете, потому что перечисление может быть основано только на примитивном числовом типе. Вы можете попробовать использовать Dictionary:

Dictionary<String, char> separators = new Dictionary<string, char>
{
    {"Comma", ','}, 
    {"Tab",  '\t'}, 
    {"Space", ' '},
};

в качестве альтернативы, вы могли бы использовать Dictionary<Separator, char> или Dictionary<Separator, string> здесь Separator это нормальное перечисление:

enum Separator
{
    Comma,
    Tab,
    Space
}

что было бы немного приятнее, чем обработка строк напрямую.

ну сначала вы пытаетесь присвоить строки не символы, даже если они всего лишь один символ. используйте вместо ",". Далее, перечисления принимают только целочисленные типы без char вы можете использовать значение unicode, но я настоятельно рекомендую вам не делать этого. Если вы уверены, что эти значения остаются неизменными, в разных культурах и языках, я бы использовал статический класс со строками const.

в то время как это действительно не возможно использовать char или string в качестве основания для перечисления, я думаю, это не то, что вам действительно нравится делать.

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

Сначала мы должны связать некоторую строку со значением перечисления. Это можно сделать с помощью DescriptionAttribute как это описано здесь или здесь.

теперь вам нужно создать список значений перечисления и соответствующие описания. Это можно сделать с помощью следующего метода:

/// <summary>
/// Creates an List with all keys and values of a given Enum class
/// </summary>
/// <typeparam name="T">Must be derived from class Enum!</typeparam>
/// <returns>A list of KeyValuePair&lt;Enum, string&gt; with all available
/// names and values of the given Enum.</returns>
public static IList<KeyValuePair<T, string>> ToList<T>() where T : struct
{
    var type = typeof(T);

    if (!type.IsEnum)
    {
        throw new ArgumentException("T must be an enum");
    }

    return (IList<KeyValuePair<T, string>>)
            Enum.GetValues(type)
                .OfType<T>()
                .Select(e =>
                {
                    var asEnum = (Enum)Convert.ChangeType(e, typeof(Enum));
                    return new KeyValuePair<T, string>(e, asEnum.Description());
                })
                .ToArray();
}

теперь у вас будет список пар ключевых значений всех перечислений и их описание. Так давайте просто назначить в качестве источника данных для поля со списком.

var comboBox = new ComboBox();
comboBox.ValueMember = "Key"
comboBox.DisplayMember = "Value";
comboBox.DataSource = EnumUtilities.ToList<Separator>();

comboBox.SelectedIndexChanged += (sender, e) =>
{
    var selectedEnum = (Separator)comboBox.SelectedValue;
    MessageBox.Show(selectedEnum.ToString());
}

пользователь видит все строковые представления enum и в ваш код вы получите желаемое значение перечисления.

класс, который эмулирует поведение перечисления, но использует string вместо int можно создать следующим образом...

public class GrainType
{
    private string _typeKeyWord;

    private GrainType(string typeKeyWord)
    {
        _typeKeyWord = typeKeyWord;
    }

    public override string ToString()
    {
        return _typeKeyWord;
    }

    public static GrainType Wheat = new GrainType("GT_WHEAT");
    public static GrainType Corn = new GrainType("GT_CORN");
    public static GrainType Rice = new GrainType("GT_RICE");
    public static GrainType Barley = new GrainType("GT_BARLEY");

}

использование...

GrainType myGrain = GrainType.Wheat;

PrintGrainKeyword(myGrain);

затем...

public void PrintGrainKeyword(GrainType grain) 
{
    Console.Writeline("My Grain code is " + grain.ToString());   // Displays "My Grain code is GT_WHEAT"
}

Это немного поздно для ответа, но, возможно, это поможет кому-то в будущем. Мне было проще использовать struct для такого рода проблем.

следующий пример-это копия вставленной части из кода MS:

namespace System.IdentityModel.Tokens.Jwt
{
    //
    // Summary:
    //     List of registered claims from different sources http://tools.ietf.org/html/rfc7519#section-4
    //     http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    public struct JwtRegisteredClaimNames
    {
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Actort = "actort";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Typ = "typ";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Sub = "sub";
        //
        // Summary:
        //     http://openid.net/specs/openid-connect-frontchannel-1_0.html#OPLogout
        public const string Sid = "sid";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Prn = "prn";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Nbf = "nbf";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string Nonce = "nonce";
        //
        // Summary:
        //     http://tools.ietf.org/html/rfc7519#section-4
        public const string NameId = "nameid";

    }
}

мы не можем определить перечисления в строковый тип. Утвержденными типами для перечисления являются byte, sbyte, short, ushort, int, uint, long или ulong.

Если вам нужна более подробная информация о перечислении,пожалуйста, перейдите по ссылке ниже, эта ссылка поможет вам понять перечисление. перечисление

@narendras1414

Класс Перечисления

 public sealed class GenericDateTimeFormatType
    {

        public static readonly GenericDateTimeFormatType Format1 = new GenericDateTimeFormatType("dd-MM-YYYY");
        public static readonly GenericDateTimeFormatType Format2 = new GenericDateTimeFormatType("dd-MMM-YYYY");

        private GenericDateTimeFormatType(string Format)
        {
            _Value = Format;
        }

        public string _Value { get; private set; }
    }

Перечисление Consuption

public static void Main()
{
       Country A = new Country();

       A.DefaultDateFormat = GenericDateTimeFormatType.Format1;

      Console.ReadLine();
}