Могу ли я дать enum атрибут в VB.NET (как я могу сделать в Java)? - PullRequest
4 голосов
/ 02 августа 2011

В Java я могу сделать что-то вроде этого:

enum Country {
    IRELAND("Europe"),
    FRANCE("Europe"),
    NIGERIA("Africa"),
    THAILAND("Asia");

    private String continent;

    Country(String continent) {
        this.continent = continent;
    }

    public String getContinent() {
        return continent;
    }
}

, что позволяет мне сделать что-то вроде:

Country country1 = getCountryFromSomewhere();
Country country2 = Country.FRANCE;
System.out.print("country1 is in " + country1.getContinent());
System.out.print("country2 is in " + country2.getContinent());

Можно ли сделать то же самое в VB.NET, т.е. добавить атрибут континента в перечисление страны?

Ответы [ 5 ]

7 голосов
/ 02 августа 2011

(Извиняюсь за повсеместное использование C # - я полагаю, что концепции больше касаются .NET, чем языка, который вы используете; надеюсь, вы лучше читаете C #, чем я пишу на VB.)

Ненепосредственно - перечисления в .NET - это просто целочисленные типы с именами для некоторых значений.

Самое близкое, что вы можете сделать в .NET, - это создать тип с фиксированным набором значений.Например, в вашем случае:

public sealed class Country
{
    public static readonly Country Ireland = new Country("Europe");
    public static readonly Country France = new Country("Europe");
    public static readonly Country Nigeria = new Country("Africa");
    public static readonly Country Thailand = new Country("Asia");

    private readonly string continent;

    public string Continent { get { return continent; } }

    private Country(string continent)
    {
        this.continent = continent;
    }
}

(я предполагаю, что VB.NET будет очень похожим.)

Обратите внимание, что это не позволяет вам переключатьсядля значений перечисления.

Если вы хотите полиморфизм, вы можете создать вложенные подклассы, которые все еще могут вызывать конструктор private , который предотвращает создание любых других подклассов.

Oneальтернативой этому является использование атрибутов для обычных перечислений:

[AttributeUsageAttribute(AttributeTargets.Field)]
public class ContinentAttribute : Attribute
{
    // etc
}

public enum Country
{
    [Continent("Europe")] Ireland = 1,
    [Continent("Europe")] France = 2,
    ...
}

Затем вам нужно будет использовать отражение, чтобы получить ContinentAttribute и получить строку.

Обратите внимание, что здесь нет действительно фиксированного набора значений - вы могли бы написать:

Country country = (Country) 15;

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

5 голосов
/ 10 сентября 2013

Вот код:

Импортирует System.ComponentModel

Импортирует System.Reflection

Public Enum enumOrderStatus
    <Description("None")>
    None
    <Description("Sent")>
    Sent
    <Description("Accepted")>
    Accepted
    <Description("Cancelled")>
    Cancelled
    <Description("Declined")>
    Declined
End Enum


Public Function GetEnumDescription(ByVal EnumConstant As [Enum]) As String
    Dim fi As FieldInfo = EnumConstant.GetType().GetField(EnumConstant.ToString())
    Dim aattr() As DescriptionAttribute = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
    If aattr.Length > 0 Then
        Return aattr(0).Description
    Else
        Return EnumConstant.ToString()
    End If
End Function
1 голос
/ 03 августа 2011

Я использовал это решение вместо:

Объявить перечисление:

Private Enum Country
    IRELAND
    FRANCE
    THAILAND
End Enum

Объявить и инициализировать словарь (он же карта):

Dim countryContinentMap As IDictionary(Of Country, String) = New Dictionary(Of Country, String)
countryContinentMap.add(Country.IRELAND, "Europe")
countryContinentMap.add(Country.FRANCE, "Europe")
countryContinentMap.add(Country.THAILAND, "Asia")

, что позволяет мне получить континент следующим образом:

Dim franceContinent As String = countryContinentMap(Country.FRANCE)
0 голосов
/ 30 ноября 2017

Создайте метод расширения для вашего Enum

Пример использования:

dim description = TableTag.Important.GetDescription()

Пример определения:

Imports System.ComponentModel
Imports System.Reflection
Imports System.Runtime.CompilerServices

Namespace Foo

  Public Enum TableTag

    <Description("Identifies tables that should be availible for writing as table or view to the model database")>
    Important

    <Description("Example for a table group that helps to select disctinct tables")>
    CustomGroup

  End Enum

  Public Module TableTagExtensions

    <Extension>
    Public Function GetDescription(enumValue As TableTag) As String

      Dim fieldInfo As FieldInfo = enumValue.GetType().GetField(enumValue.ToString())
      Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())

      If attributes.Length > 0 Then
        Return attributes(0).Description
      Else
        Return enumValue.ToString()
      End If

    End Function

  End Module

End Namespace
0 голосов
/ 20 июля 2016

Вот как я решил это в своем приложении. Все еще ищу что-то еще проще.

Что вы думаете об этом?

Public Sub Init()
    Dim values() As Integer = CType([Enum].GetValues(GetType(MyEnum)), Integer())
    For i As Integer = 0 To values.Count - 1
        Me.contextMenuInGUI.Items.Add(Me.GetEnumDescription(i))
    Next
End Sub

Private Function GetEnumDescription(ByVal i As Integer) As String
    Select Case i
        Case MyEnum.Comment
            Return "Description for Comment"

        Case MyEnum.SomeEnumValueInCamelCase
            Return "Value without camel case (€)(%)(@)"
    End Select
    Return "Add a case in Class:GetEnumDescription"
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...