在C#中,Java的枚举相当于什么?

在C#中,Java的枚举相当于什么?

C#中没有完整的Java枚举function。 您可以使用嵌套类型和私有构造函数来合理地关闭。 例如:

 using System; using System.Collections.Generic; using System.Xml.Linq; public abstract class Operator { public static readonly Operator Plus = new PlusOperator(); public static readonly Operator Minus = new GenericOperator((x, y) => x - y); public static readonly Operator Times = new GenericOperator((x, y) => x * y); public static readonly Operator Divide = new GenericOperator((x, y) => x / y); // Prevent other top-level types from instantiating private Operator() { } public abstract int Execute(int left, int right); private class PlusOperator : Operator { public override int Execute(int left, int right) { return left + right; } } private class GenericOperator : Operator { private readonly Func op; internal GenericOperator(Func op) { this.op = op; } public override int Execute(int left, int right) { return op(left, right); } } } 

当然,您不必使用嵌套类型,但它们提供了方便的“自定义行为”部分,Java枚举很适合。 在其他情况下,您只需将参数传递给私有构造函数即可获得一组众所周知的受限值。

这件事没有给你一些:

  • 顺序支持
  • 切换支持
  • EnumSet
  • 序列化/反序列化(作为单例)

其中一些可能是通过足够的努力来完成的,但如果没有hackery,切换就不可行。 现在,如果语言做了这样的事情,那么通过使hackery自动化(例如,自动声明一个const字段的加载,并将enum类型上的任何切换更改为整数切换,只允许“已知的“案例”。

哦,部分类型意味着您不必在同一个文件中包含所有枚举值。 如果每个值都相关(绝对可能),每个值都可以有自己的文件。

枚举是少数语言function之一,在java中比c#更好地实现。 在java中,枚举是完全成熟的命名类型实例,而c#枚举基本上是命名常量。

话虽如此,对于基本情况,它们看起来很相似。 但是在java中,你有更强大的function,因为你可以为各个枚举添加行为,因为它们是完整的类。

你正在寻找一些特别的function吗?

这是另一个有趣的想法。 我想出了以下Enumeration基类:

 public abstract class Enumeration where T : Enumeration { protected static int nextOrdinal = 0; protected static readonly Dictionary> byOrdinal = new Dictionary>(); protected static readonly Dictionary> byName = new Dictionary>(); protected readonly string name; protected readonly int ordinal; protected Enumeration(string name) : this (name, nextOrdinal) { } protected Enumeration(string name, int ordinal) { this.name = name; this.ordinal = ordinal; nextOrdinal = ordinal + 1; byOrdinal.Add(ordinal, this); byName.Add(name, this); } public override string ToString() { return name; } public string Name { get { return name; } } public static explicit operator int(Enumeration obj) { return obj.ordinal; } public int Ordinal { get { return ordinal; } } } 

它基本上只有一个类型参数,因此序数可以在不同的派生枚举中正常工作。 然后上面的Jon的Operator示例变为:

 public class Operator : Enumeration { public static readonly Operator Plus = new Operator("Plus", (x, y) => x + y); public static readonly Operator Minus = new Operator("Minus", (x, y) => x - y); public static readonly Operator Times = new Operator("Times", (x, y) => x * y); public static readonly Operator Divide = new Operator("Divide", (x, y) => x / y); private readonly Func op; // Prevent other top-level types from instantiating private Operator(string name, Func op) :base (name) { this.op = op; } public int Execute(int left, int right) { return op(left, right); } } 

这提供了一些优点。

  • 顺序支持
  • 转换为stringint ,使switch语句可行
  • GetType()将为派生的Enumeration类型的每个值提供相同的结果。
  • 可以将System.Enum的Static方法添加到基本Enumeration类中以允许相同的function。

您可能可以使用我们在Java中使用的旧类型安全枚举模式,然后才能获得真实模式(假设C#中的那些不是作为注释声明的类)。 该模式在本页中间之前描述

 //Review the sample enum below for a template on how to implement a JavaEnum. //There is also an EnumSet implementation below. public abstract class JavaEnum : IComparable { public static IEnumerable Values { get { throw new NotImplementedException("Enumeration missing"); } } public readonly string Name; public JavaEnum(string name) { this.Name = name; } public override string ToString() { return base.ToString() + "." + Name.ToUpper(); } public int CompareTo(object obj) { if(obj is JavaEnum) { return string.Compare(this.Name, ((JavaEnum)obj).Name); } else { throw new ArgumentException(); } } //Dictionary values are of type SortedSet private static Dictionary enumDictionary; public static SortedSet RetrieveEnumValues() where T : JavaEnum { if(enumDictionary == null) { enumDictionary = new Dictionary(); } object enums; if(!enumDictionary.TryGetValue(typeof(T), out enums)) { enums = new SortedSet(); FieldInfo[] myFieldInfo = typeof(T).GetFields(BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public); foreach(FieldInfo f in myFieldInfo) { if(f.FieldType == typeof(T)) { ((SortedSet)enums).Add((T)f.GetValue(null)); } } enumDictionary.Add(typeof(T), enums); } return (SortedSet)enums; } } //Sample JavaEnum public class SampleEnum : JavaEnum { //Enum values public static readonly SampleEnum A = new SampleEnum("A", 1); public static readonly SampleEnum B = new SampleEnum("B", 2); public static readonly SampleEnum C = new SampleEnum("C", 3); //Variables or Properties common to all enums of this type public int int1; public static int int2 = 4; public static readonly int int3 = 9; //The Values property must be replaced with a call to JavaEnum.generateEnumValues() to generate an IEnumerable set. public static new IEnumerable Values { get { foreach(var e in JavaEnum.RetrieveEnumValues()) { yield return e; } //If this enum should compose several enums, add them here //foreach(var e in ChildSampleEnum.Values) { // yield return e; //} } } public SampleEnum(string name, int int1) : base(name) { this.int1 = int1; } } public class EnumSet : SortedSet where T : JavaEnum { // Creates an enum set containing all of the elements in the specified element type. public static EnumSet AllOf(IEnumerable values) { EnumSet returnSet = new EnumSet(); foreach(T item in values) { returnSet.Add(item); } return returnSet; } // Creates an enum set with the same element type as the specified enum set, initially containing all the elements of this type that are not contained in the specified set. public static EnumSet ComplementOf(IEnumerable values, EnumSet set) { EnumSet returnSet = new EnumSet(); foreach(T item in values) { if(!set.Contains(item)) { returnSet.Add(item); } } return returnSet; } // Creates an enum set initially containing all of the elements in the range defined by the two specified endpoints. public static EnumSet Range(IEnumerable values, T from, T to) { EnumSet returnSet = new EnumSet(); if(from == to) { returnSet.Add(from); return returnSet; } bool isFrom = false; foreach(T item in values) { if(isFrom) { returnSet.Add(item); if(item == to) { return returnSet; } } else if(item == from) { isFrom = true; returnSet.Add(item); } } throw new ArgumentException(); } // Creates an enum set initially containing the specified element(s). public static EnumSet Of(params T[] setItems) { EnumSet returnSet = new EnumSet(); foreach(T item in setItems) { returnSet.Add(item); } return returnSet; } // Creates an empty enum set with the specified element type. public static EnumSet NoneOf() { return new EnumSet(); } // Returns a copy of the set passed in. public static EnumSet CopyOf(EnumSet set) { EnumSet returnSet = new EnumSet(); returnSet.Add(set); return returnSet; } // Adds a set to an existing set. public void Add(EnumSet enumSet) { foreach(T item in enumSet) { this.Add(item); } } // Removes a set from an existing set. public void Remove(EnumSet enumSet) { foreach(T item in enumSet) { this.Remove(item); } } } 

枚举 ,或者你需要一些特别的Java枚举,但c#没有?

Interesting Posts