[英]Can I give an enum an attribute in VB.NET (like I can do in Java)?
In Java I can do something like this: 在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;
}
}
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 ie add the continent attribute to the country enum? 是否可以在VB.NET中执行相同的操作,即将continent属性添加到国家/地区枚举?
(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.) (在整个过程中使用C#的道歉 - 我相信这些概念更多的是关于.NET而不是你碰巧使用的语言;希望你在阅读C#时比在编写VB时更好。)
Not directly - enums in .NET are just integer types with names for some of the values. 不直接 - .NET中的枚举只是整数类型,其中包含某些值的名称。
The closest you can come in .NET is to create a type with a fixed set of values. .NET中最接近的是创建一个具有固定值集的类型。 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.) (我假设VB.NET非常相似。)
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. 然后,您需要使用反射来获取
ContinentAttribute
并检索字符串。
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).
早期的解决方案并非如此,在这种解决方案中,您实际上只限于那些少数值(和null)。
Here is the code: 这是代码:
Imports System.ComponentModel 导入System.ComponentModel
Imports System.Reflection 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
I used this solution instead: 我使用这个解决方案:
Declare enum: 声明枚举:
Private Enum Country
IRELAND
FRANCE
THAILAND
End Enum
Declare and initialise Dictionary (aka a map): 声明并初始化Dictionary(又名地图):
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")
which allows me to get the continent like this: 这让我能够像这样进入大陆:
Dim franceContinent As String = countryContinentMap(Country.FRANCE)
Here is how I solved this in my application. 以下是我在应用程序中解决这个问题的方法。 Still looking for something even easier.
还在寻找更容易的东西。
What do you think about it? 你怎么看待这件事?
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
Create an extension method for your Enum 为您的Enum创建扩展方法
Usage example: 用法示例:
dim description = TableTag.Important.GetDescription()
Definition example: 定义示例:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.