Возможный иметь строки для перечислений?

VC6 был несовместим по умолчанию в этом отношении. VC6 new возвратился 0 (или NULL).

Вот Статья КБ Microsoft об этой проблеме наряду с их предложенным обходным решением с помощью пользовательского new обработчик:

, Если у Вас есть старый код, который был написан для поведения VC6, можно получить то же самое поведение с более новыми компиляторами MSVC (что-то как 7,0 и позже) путем соединения в объектном файле, названном nothrownew.obj. Существует на самом деле справедливо сложный подшипник в 7,0 и 7,1 компиляторах (VS2002 и VS2003), чтобы определить, приняли ли они значение по умолчанию к неброску или броску new.

кажется, что мс убрала это в 8,0 (VS2005) — теперь это всегда принимает значение по умолчанию к броску, новому, если Вы конкретно не связываетесь с nothrownew.obj.

Примечание, что можно указать, что Вы хотите new возвратиться 0 вместо того, чтобы бросить std::bad_alloc использование std::nothrow параметр:

SomeType *p = new(std::nothrow) SomeType;

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

7
задан Joan Venge 16 October 2009 в 17:48
поделиться

11 ответов

using System.ComponentModel;   
enum FilterType
{
    [Description("Rigid")]
    Rigid,
    [Description("Soft / Glow")]
    SoftGlow,
    [Description("Ghost")]
    Ghost ,
}

Вы можете получить значение следующим образом

public static String GetEnumerationDescription(Enum e)
{
  Type type = e.GetType();
  FieldInfo fieldInfo = type.GetField(e.ToString());
  DescriptionAttribute[] da = (DescriptionAttribute[])(fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false));
  if (da.Length > 0)
  {
    return da[0].Description;
  }
  return e.ToString();
}
11
ответ дан 6 December 2019 в 06:24
поделиться

Нет, но если вы хотите охватить строки "const" и использовать их как перечисление, вот что я делаю:

public static class FilterType
{
   public const string Rigid = "Rigid";
   public const string SoftGlow =  "Soft / Glow";
   public const string Ghost ="Ghost";
}
9
ответ дан 6 December 2019 в 06:24
поделиться

Перечисления всегда связаны с целочисленным значением. Так что нет. Вы можете использовать FilterType.Rigid.ToString () для получения строкового значения, хотя его нельзя локализовать напрямую.

1
ответ дан 6 December 2019 в 06:24
поделиться

Нет, но вы можете обмануть вот так:

public enum FilterType{
   Rigid,
   SoftGlow,
   Ghost
}

А затем, когда вам понадобятся их строковые значения, вы можете просто выполнить FilterType.Rigid.ToString ()

1
ответ дан 6 December 2019 в 06:24
поделиться

Вы можете получить имя Enum в виде строки вроде этой

FilterType myType = FilterType.Rigid;
String strType = myType.ToString();

Однако вы можете застрять с верблюжьей нотацией / венгерской нотацией, но вы можете легко преобразовать ее в более удобную для пользователя строку используя такой метод (не самое красивое решение, я был бы признателен за вклад в его оптимизацию):

Public Shared Function NormalizeCamelCase(ByVal str As String) As String

    If String.IsNullOrEmpty(str) Then
        Return String.Empty
    End If

    Dim i As Integer = 0
    Dim upperCount As Integer = 0
    Dim otherCount As Integer = 0
    Dim normalizedString As String = str

    While i < normalizedString.Length

        If Char.IsUpper(normalizedString, i) Then
            ''Current char is Upper Case
            upperCount += 1
            If i > 0 AndAlso Not normalizedString(i - 1).Equals(" "c) Then
                ''Current char is not first and preceding char is not a space
                ''...insert a space, move to next char
                normalizedString = normalizedString.Insert(i, " ")
                i += 1
            End If
        ElseIf Not Char.IsLetter(normalizedString, i) Then
            otherCount += 1
        End If

        ''Move to next char
        i += 1

    End While

    If upperCount + otherCount = str.Length Then
        ''String is in all caps, return original string 
        Return str
    Else
        Return normalizedString
    End If

End Function

Если этого все еще недостаточно, вы можете изучить Custom Attributes, которые можно получить с помощью Reflection ...

1
ответ дан 6 December 2019 в 06:24
поделиться

Вы можете использовать Атрибут над значениями

[System.ComponentModel.Description("Rigid")]

, пример:

 enum FilterType
{
   [System.ComponentModel.Description("Rigid")]
   Rigid,
    [System.ComponentModel.Description("Soft / Glow")]
   SoftGlow,
    [System.ComponentModel.Description("Ghost")]
   Ghost
}

и использовать Отражение для получения описаний.

Метод расширения Enum:

public static string GetDescription(this Enum en)
    {
        var type = en.GetType();
        var memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {
            var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }
        return en.ToString();
    }

используйте его:

FilterType = FilterType.Rigid;
            string description= result.GetDescription();
0
ответ дан 6 December 2019 в 06:24
поделиться

Нет, это невозможно.

Утвержденные типы для перечисления: байт, sbyte, короткий, ushort, int, uint, long или ulong.

Однако вы можете получить объявленное имя перечисления с помощью класса Enum:

string name = Enum.GetName(typeof(FilterType), FilterType.Rigid);

Если это не сработает для вас, возможно, коллекция строковых констант, собранных в классе.

0
ответ дан 6 December 2019 в 06:24
поделиться

По аналогии с примером Шона Боу, вы также можете сделать это на C # 3 с помощью метода расширения для enum (я не придумал и не могу, черт возьми, вспомнить, где я сделал).

Создать атрибут:

public class DisplayTextAttribute : Attribute {
  public DisplayTextAttribute(String text) {
  Text = text;
  }
  public string Text { get; set; }
}

Создать расширение:

public static class EnumHelpers {
  public static string GetDisplayText(this Enum enumValue) {
    var type = enumValue.GetType();
    MemberInfo[] memberInfo = type.GetMember(enumValue.ToString());

    if (memberInfo == null || memberInfo.Length == 0)
      return enumValue.ToString();

    object[] attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayTextAttribute), false);
    if (attributes == null || attributes.Length == 0)
      return enumValue.ToString();

    return ((DisplayTextAttribute)attributes[0]).Text;
  }
}

Я нашел это действительно аккуратным решением. В свое перечисление добавьте следующее:

enum FilterType{
  Rigid,
  [DisplayText("Soft / Glow")]
  SoftGlow,
  Ghost
}

Затем вы можете получить доступ к FilterType.GetDisplayText () , который вернет строку для перечислений без атрибутов и displayText для перечислений с атрибутами.

0
ответ дан 6 December 2019 в 06:24
поделиться

Это невозможно. C # допускает только целые типы перечислений (int, short, long и т. Д.). Вы можете создать облегченный класс, похожий на перечисление, или использовать статические константы.

static class FilterTypes
{
    public const string Rigid = "Rigid";
    // ...
}

// or ...

class FilterType
{
    static readonly FilterType RigidFilterType = new FilterType("Rigid");

    string name;

    FilterType(string name)  // private constructor
    {
        this.name = name;
    }

    public static FilterType Rigid
    {
        get { return FilterType.RigidFilterType; }
    }

    // ...
}
1
ответ дан 6 December 2019 в 06:24
поделиться

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

//Can return string constants, the results of a Database call, 
//or anything else you need to do to get the correct value 
//(for localization, for example)
public static string EnumValue(this MyEnum e) {
    switch (e) {
        case MyEnum.First:
            return "First Friendly Value";
        case MyEnum.Second:
            return "Second Friendly Value";
        case MyEnum.Third:
            return "Third Friendly Value";
    }
    return "Horrible Failure!!";
}

Таким образом вы можете сделать:

Private MyEnum value = MyEnum.First;
Console.WriteLine(value.EnumValue());
2
ответ дан 6 December 2019 в 06:24
поделиться

Переносимого способа не существует. Однако есть несколько непереносимых решений.

Во-первых, как уже упоминалось другими, Windows предоставляет нестандартные __ try и __ за исключением фреймворка, называемого Structured Exeption Handling ( ваш конкретный ответ находится в базе знаний).

Во-вторых, alloca - при правильной реализации - может сказать вам, собирается ли стек переполниться:

bool probe_stack(size_t needed_stack_frame_size)
{
    return NULL != alloca(needed_stack_frame_size);
};

I как и этот подход, потому что в конце probe_stack выделенная память alloca освобождается и становится доступной для вашего использования. К сожалению, только несколько операционных систем правильно реализуют alloca . alloca никогда не возвращает NULL в большинстве операционных систем, позволяя вам обнаружить, что стек переполнен, и произошел впечатляющий сбой.

В-третьих, UNIX-подобные системы часто имеют заголовок, называемый ucontext.h , с функциями для установки размера стека (или, фактически, соединить несколько стопок вместе). Вы можете отслеживать свое положение в стеке и определять, не произойдет ли переполнение. Windows имеет аналогичные возможности а-ля CreateFiber .


Начиная с Windows 8, Windows имеет функцию специально для этого ( GetCurrentThreadStackLimits )

и определите, не собираетесь ли вы переполниться. Windows имеет аналогичные возможности а-ля CreateFiber .


Начиная с Windows 8, Windows имеет функцию специально для этого ( GetCurrentThreadStackLimits )

и определите, не собираетесь ли вы переполниться. Windows имеет аналогичные возможности а-ля CreateFiber .


Начиная с Windows 8, Windows имеет функцию специально для этого ( GetCurrentThreadStackLimits )

enum FilterType
{
   Rigid,
   [Description("Soft / Glow")]
   SoftGlow,
   Ghost,
}

Затем, чтобы получить описание и перейти к ToString ()

var descriptionAttribute = Value.GetType()
 .GetField(Value.ToString())
 .GetCustomAttributes(typeof(DescriptionAttribute), false)
 .OfType <DescriptionAttribute>()
 .FirstOrDefault()??new DescriptionAttribute(Value.ToString());
1
ответ дан 6 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: