public enum OperatorType
{
GreaterOrEqual (">=", "GreaterOrEqual"),
Greater (">" ,"Greater"),
Less ("<", "Less"),
LessOrEqual ("<=", "LessOrEqual"),
Equal ("==", "Equal"),
Between ("Between", "Between"),
Around ("Around","Around");
private final String symbol;
private final String name;
private OperatorType(final String symbol, final String name) {
this.symbol = symbol;
this.name = name;
}
}
然后添加一个迭代values()的静态方法,将所有数据添加到hashmap中,并允许通过其中一个属性作为键从地图中检索完整枚举数据。
简而言之,enum是java中非常发达的类型。
现在,
转到c#,我的选择是什么?
我想要保存带有属性的枚举,将其加载到地图中,并在需要时按键进行检索。我有什么可以帮助的吗(比如,每个枚举的单音 - 这不是一个好主意)
感谢。
答案 0 :(得分:8)
我只想创建一个类,每个类型的public static readonly
个实例和ditch enums。您可以将它们用作字典键或做任何您喜欢的事情。如果您仍打算将它们映射到基础数据类型(int
),那么您也可以为此创建隐式运算符。
public class OperatorType
{
private static readonly Dictionary<int, OperatorType> OperatorMapping = new Dictionary<int, OperatorType>();
public static readonly OperatorType GreaterOrEqual = new OperatorType(0, ">=", "GreaterOrEqual");
public static readonly OperatorType Greater = new OperatorType(1, ">", "Greater");
public readonly String symbol;
public readonly String name;
private readonly int underlyingValue;
private OperatorType(int underlyingValue, string symbol, string name) {
this.underlyingValue = underlyingValue;
OperatorMapping[underlyingValue] = this;
this.symbol = symbol;
this.name = name;
}
public static implicit operator int(OperatorType operatorType)
{
return operatorType.underlyingValue;
}
public static implicit operator OperatorType(int value)
{
return OperatorMapping[value];
}
}
样本用法:
Dictionary<OperatorType, string> operators = new Dictionary<OperatorType, string>();
operators.Add(OperatorType.GreaterOrEqual, "Greater or equal");
Console.WriteLine(operators[OperatorType.GreaterOrEqual]); //"Greater or equal"
OperatorType operatorType = 1;
Console.WriteLine(operatorType.name); //"Greater"
如果您不关心基础价值,请不要包含它。还要考虑Dictionary
映射是否应该是您使用的线程安全。如果需要,还可以公开静态IEnumerable<OperatorType>
(或其他集合)以定义所有运算符。
编辑:第二个想法,explicit
运算符可能更可取代implicit
,以符合典型的.NET最佳做法,并更好地匹配典型的enum
转换。
答案 1 :(得分:4)
最方便的解决方法可能是为枚举类型创建一个扩展方法,并返回相关的符号。
这样的事情:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
tester t = tester.x;
t.testenums();
Console.ReadKey();
}
}
public static class ext
{
public static void testenums(this tester x)
{
Console.WriteLine(x.ToString());
}
}
public enum tester
{
x,
y
}
}
当然你可以编写一个更复杂的扩展方法,带有返回值等,这只是一个如何做的例子。
答案 2 :(得分:2)
C#实际上没有相同的功能。然而,有几种可能性非常接近(也可能更灵活)。
坚持常规枚举,您可以使用属性来丰富额外信息。当然,这需要反思才能与
一起使用public enum OperatorType
{
[DisplayName(">=")]
GreaterOrEqual,
// ...
}
有几种模式适用于此,例如http://www.codeproject.com/Articles/28087/DisplayNameAttribute-for-Enumerations,谷歌了解更多。
另一种方法是使用常规类来增强枚举类型:
public class OperatorType
{
public static OperatorType GreaterOrEqual = new OperatorType(">=", "GreaterOrEqual");
// ...
string symbol;
string name;
private OperatorType(string symbol, string name)
{
this.symbol = symbol;
this.name = name;
}
}
This article描述了在C#
中使用类似枚举类型的其他一些方法答案 3 :(得分:2)
您可以创建一个属性:
public class EnumKeyAttribute : Attribute
{
public string Key { get; set; }
public string Description { get; set; }
public EnumKeyAttribute(string key, string description)
{
this.Key = key;
this.Description = description;
}
}
然后将其应用于您的枚举
public enum OperatorType
{
[EnumKey(">=", "GreaterOrEqual")]
GreaterOrEqual,
[EnumKey(">", "Greater")]
Greater,
[EnumKey("<", "Less")]
Less,
[EnumKey("<=", "LessOrEqual")]
LessOrEqual,
[EnumKey("==", "Equal")]
Equal,
[EnumKey("Between", "Between")]
Between,
[EnumKey("Around", "Around")]
Around
}
要获取属性数据,您可以使用反射。以下是获取“Less”
属性的示例 MemberInfo memberInfo = typeof(OperatorType).GetMember(OperatorType.Less.ToString()).FirstOrDefault();
if(memberInfo != null)
{
EnumKeyAttribute attribute = (EnumKeyAttribute)memberInfo.GetCustomAttributes(typeof(EnumKeyAttribute), false).FirstOrDefault();
Console.WriteLine(attribute.Key);
Console.WriteLine(attribute.Description);
}
但是因为这些枚举不是在运行时创建的,所以可以通过创建一个在字典中查找值的静态方法来提高效率。这是一种易于使用的扩展方法
public static class KeyFinder
{
private static Dictionary<OperatorType, EnumKeyAttribute> lookupTable =
new Dictionary<OperatorType, EnumKeyAttribute>();
public static EnumKeyAttribute GetKey(this OperatorType type)
{
if (lookupTable.ContainsKey(type))
{
return lookupTable[type];
}
MemberInfo memberInfo = typeof(OperatorType).GetMember(type.ToString()).FirstOrDefault();
if (memberInfo != null)
{
EnumKeyAttribute attribute = (EnumKeyAttribute)memberInfo.GetCustomAttributes(typeof(EnumKeyAttribute), false).FirstOrDefault();
if (attribute != null)
{
lookupTable.Add(type, attribute);
return attribute;
}
}
// add a null value so next time it doesn't use reflection only to find nothing
lookupTable.Add(type, null);
return null;
}
}
现在要获取值,您只需执行以下操作:
OperatorType.Less.GetKey().Key
OperatorType.Less.GetKey().Description
请注意空引用异常(因为如果找不到属性,它将返回null)。如果要按键查找,只需创建其他使用字符串值作为键的扩展方法。
答案 4 :(得分:0)
如果你真的需要C#中Java风格枚举的功能,我会看到三种合理的方法来实现它:
使用C#枚举和静态类辅助方法。你失去了类型安全性,但这是一个非常可行的解决方案。
使用C#枚举和一组扩展方法。可能是最惯用的C#解决方案,但您仍然需要处理类型安全性的损失(您的扩展方法应该能够处理超出范围的值,即使只是抛出异常)。
< / LI>在Java 5中获得enum
关键字的语言之前,使用Java中常见的type-safe enum pattern。如果每个枚举值都有非平凡的逻辑,那么这将是我的偏好