Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I give an enum an attribute in VB.NET (like I can do in Java)?

Tags:

java

enums

vb.net

In Java I can do something like this:

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

    private String continent;

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

    public String getContinent() {
        return continent;
    }
}

which allows me to do something like:

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

Is it possible to do the same thing in VB.NET i.e. add the continent attribute to the country enum?

like image 284
CodeClimber Avatar asked Aug 02 '11 16:08

CodeClimber


People also ask

Can enum have attributes Java?

An enum can, just like a class , have attributes and methods. The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden). An enum cannot be used to create objects, and it cannot extend other classes (but it can implement interfaces).

Why we should not use enum in Java?

With an enum it can get more complicated due to having separate values for name and toString, and those values possibly being used in conditional logic.

What is enum in VB net?

An enumeration has a name, an underlying data type, and a set of members. Each member represents a constant. An enumeration declared at class, structure, module, or interface level, outside any procedure, is a member enumeration. It is a member of the class, structure, module, or interface that declares it.


2 Answers

(Apologies for using C# throughout - I believe the concepts are more about .NET than the language you happen to use; hopefully you're better at reading C# than I am at writing VB.)

Not directly - enums in .NET are just integer types with names for some of the values.

The closest you can come in .NET is to create a type with a fixed set of values. For example, in your case:

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;
    }
}

(I assume the VB.NET would be very similar.)

Note that this doesn't let you switch on the enum values.

If you want polymorphism, you can create nested subclasses which can still call the private constructor, which prevents any other subclasses being created.

One alternative to this is to use attributes on normal enums:

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

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

You'd then need to use reflection to get at the ContinentAttribute and retrieve the string.

Note that here there isn't really a fixed set of values - you could write:

Country country = (Country) 15;

At that point you can't get the continent for it, and if you pass it to any methods which expect it to be a real country, you've got problems. That isn't the case with the earlier solution, where you really are restricted to those few values (and null).

like image 145
Jon Skeet Avatar answered Oct 19 '22 23:10

Jon Skeet


Here is the code:

Imports System.ComponentModel

Imports 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
like image 27
Kim Avatar answered Oct 19 '22 23:10

Kim