C # vs Java Enum (C # için yeni olanlar için)


182

Bir süredir Java'da programlama yapıyorum ve tamamen C # ile yazılmış bir projeye atıldım. C # hızlandırmak için gelmeye çalışıyorum ve yeni projemde çeşitli yerlerde kullanılan enums fark ettim, ama ilk bakışta, C # enums Java 1.5 + uygulama daha basit gibi görünüyor. Herkes C # ve Java numaralandırmalar arasındaki farkları numaralandırabilir ve nasıl üstesinden gelebilir? (Bir dil alev savaşı başlatmak istemiyorum, sadece C # 'da Java'da yaptığım bazı şeyleri nasıl yapacağımı bilmek istiyorum). Örneğin, birisi Sun'ın ünlü Planet enum örneğine bir C # muadili gönderebilir mi?

public enum Planet {
  MERCURY (3.303e+23, 2.4397e6),
  VENUS   (4.869e+24, 6.0518e6),
  EARTH   (5.976e+24, 6.37814e6),
  MARS    (6.421e+23, 3.3972e6),
  JUPITER (1.9e+27,   7.1492e7),
  SATURN  (5.688e+26, 6.0268e7),
  URANUS  (8.686e+25, 2.5559e7),
  NEPTUNE (1.024e+26, 2.4746e7),
  PLUTO   (1.27e+22,  1.137e6);

  private final double mass;   // in kilograms
  private final double radius; // in meters
  Planet(double mass, double radius) {
      this.mass = mass;
      this.radius = radius;
  }
  public double mass()   { return mass; }
  public double radius() { return radius; }

  // universal gravitational constant  (m3 kg-1 s-2)
  public static final double G = 6.67300E-11;

  public double surfaceGravity() {
      return G * mass / (radius * radius);
  }
  public double surfaceWeight(double otherMass) {
      return otherMass * surfaceGravity();
  }
}

// Example usage (slight modification of Sun's example):
public static void main(String[] args) {
    Planet pEarth = Planet.EARTH;
    double earthRadius = pEarth.radius(); // Just threw it in to show usage

    // Argument passed in is earth Weight.  Calculate weight on each planet:
    double earthWeight = Double.parseDouble(args[0]);
    double mass = earthWeight/pEarth.surfaceGravity();
    for (Planet p : Planet.values())
       System.out.printf("Your weight on %s is %f%n",
                         p, p.surfaceWeight(mass));
}

// Example output:
$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
[etc ...]

1
@ycomp Bunun için kredi alamıyorum. Sun'dan (şimdi Oracle) geliyor: docs.oracle.com/javase/tutorial/java/javaOO/enum.html
Ogre Psalm33

Yanıtlar:


210

CLR'deki numaralandırmalara basitçe sabitler adı verilir. Temel alınan tür ayrılmaz olmalıdır. Java'da bir numaralandırma daha çok türün adlandırılmış bir örneğine benzer. Bu tür oldukça karmaşık olabilir ve - örneğin gösterdiği gibi - çeşitli türlerde birden çok alan içerebilir.

Örneği C # 'a bağlamak için, numaralandırmayı değişmez bir sınıfa dönüştürür ve o sınıfın salt okunur statik örneklerini gösteririm:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Planet planetEarth = Planet.MERCURY;

            double earthRadius = pEarth.Radius; // Just threw it in to show usage
            double earthWeight = double.Parse("123");
            double earthMass   = earthWeight / pEarth.SurfaceGravity();

            foreach (Planet p in Planet.Values)
                Console.WriteLine($"Your weight on {p} is {p.SurfaceWeight(mass)}");

            Console.ReadKey();
        }
    }

    public class Planet
    {
        public static readonly Planet MERCURY = new Planet("Mercury", 3.303e+23, 2.4397e6);
        public static readonly Planet VENUS   = new Planet("Venus", 4.869e+24, 6.0518e6);
        public static readonly Planet EARTH   = new Planet("Earth", 5.976e+24, 6.37814e6);
        public static readonly Planet MARS    = new Planet("Mars", 6.421e+23, 3.3972e6);
        public static readonly Planet JUPITER = new Planet("Jupiter", 1.9e+27, 7.1492e7);
        public static readonly Planet SATURN  = new Planet("Saturn", 5.688e+26, 6.0268e7);
        public static readonly Planet URANUS  = new Planet("Uranus", 8.686e+25, 2.5559e7);
        public static readonly Planet NEPTUNE = new Planet("Neptune", 1.024e+26, 2.4746e7);
        public static readonly Planet PLUTO   = new Planet("Pluto", 1.27e+22, 1.137e6);

        public static IEnumerable<Planet> Values
        {
            get
            {
                yield return MERCURY;
                yield return VENUS;
                yield return EARTH;
                yield return MARS;
                yield return JUPITER;
                yield return SATURN;
                yield return URANUS;
                yield return NEPTUNE;
                yield return PLUTO;
            }
        }

        public string Name   { get; private set; }
        public double Mass   { get; private set; }
        public double Radius { get; private set; }

        Planet(string name, double mass, double radius) => 
            (Name, Mass, Radius) = (name, mass, radius);

        // Wniversal gravitational constant  (m3 kg-1 s-2)
        public const double G = 6.67300E-11;
        public double SurfaceGravity()            => G * mass / (radius * radius);
        public double SurfaceWeight(double other) => other * SurfaceGravity();
        public override string ToString()         => name;
    }
}

4
Java 1.4 ve aşağısını kullanmaya zorlanan yoksul insanların bu tür bir tür güvenli enum uygulamasıdır ... Java 5'in enumları, özellikle anahtar ifadelerinde kullanılabildikleri için Java 5+'nin belki de en iyi özelliğidir.
MetroidFan2002

9
@Chris: sadece bayrak numaralandırmaları çoğullaştırılmalıdır. Yani, üyeleri | Şebeke.
Kent Boogaart

5
@Mladen: Tamamen bağlama bağlıdır. Sınırlı sayıda gezegene erişim sağlayan bir oyuna mükemmel bir gezegen sayımı uygun olabilir. Oyuna yeni bir gezegen eklenirse, koddaki değişiklikler tam olarak istediğiniz şey olabilir.
Kent Boogaart

3
@Richie_W Değerler özelliğini kullanarak numaralandırmalar üzerinde yineleme yapabilirsiniz.
Jonathan

23
Vay be ... C # 'da Java'dan daha ayrıntılı bir şekilde uygulanan bir şey görmek neredeyse inanılmaz
Sune Rasmussen

218

C # 'da numaralandırmalarda uzantı yöntemlerini tanımlayabilirsiniz ve bu, eksik işlevselliklerden bazılarını oluşturur.

PlanetBir enum olarak tanımlayabilir ve ayrıca surfaceGravity()ve ile eşdeğer uzantı yöntemlerine sahip olabilirsiniz surfaceWeight().

Mikhail tarafından önerilen özel özellikleri kullandım , ancak aynı sözlük kullanılarak da elde edilebilir.

using System;
using System.Reflection;

class PlanetAttr: Attribute
{
    internal PlanetAttr(double mass, double radius)
    {
        this.Mass = mass;
        this.Radius = radius;
    }
    public double Mass { get; private set; }
    public double Radius { get; private set; }
}

public static class Planets
{
    public static double GetSurfaceGravity(this Planet p)
    {
        PlanetAttr attr = GetAttr(p);
        return G * attr.Mass / (attr.Radius * attr.Radius);
    }

    public static double GetSurfaceWeight(this Planet p, double otherMass)
    {
        return otherMass * p.GetSurfaceGravity();
    }

    public const double G = 6.67300E-11;

    private static PlanetAttr GetAttr(Planet p)
    {
        return (PlanetAttr)Attribute.GetCustomAttribute(ForValue(p), typeof(PlanetAttr));
    }

    private static MemberInfo ForValue(Planet p)
    {
        return typeof(Planet).GetField(Enum.GetName(typeof(Planet), p));
    }

}

public enum Planet
{
    [PlanetAttr(3.303e+23, 2.4397e6)]  MERCURY,
    [PlanetAttr(4.869e+24, 6.0518e6)]  VENUS,
    [PlanetAttr(5.976e+24, 6.37814e6)] EARTH,
    [PlanetAttr(6.421e+23, 3.3972e6)]  MARS,
    [PlanetAttr(1.9e+27,   7.1492e7)]  JUPITER,
    [PlanetAttr(5.688e+26, 6.0268e7)]  SATURN,
    [PlanetAttr(8.686e+25, 2.5559e7)]  URANUS,
    [PlanetAttr(1.024e+26, 2.4746e7)]  NEPTUNE,
    [PlanetAttr(1.27e+22,  1.137e6)]   PLUTO
}

20
Bunun daha fazla oylanması gerektiğini düşünüyorum. Java'daki numaraların nasıl çalıştığına daha yakın. Planet.MERCURY.GetSurfaceGravity () <gibi bir şey yapabilirim - Bir Enum uzantı yöntemine dikkat edin!
thenonhacker

2
Kesinlikle evet. Numaralandırmalarda genişletme yöntemleri (heck, genel olarak genişletme yöntemleri) C # için harika bir ektir.
KeithS

3
@AllonGuralnek Teşekkürler. Herkes meta veriler konusunda hemfikir olmaz. MattDavey'in ilgili kodlayıcı.stackexchange sorusundaki yorumuna bakın .
finnw

@finnw: Code Review SE sitesini hiç duymadım - bunun için teşekkürler! Orada bu tartışmaya devam ediyorum (her ne kadar burada Programcılar'da kendi sorusunu hak edebilir).
Allon Güralnek

Bu harika bir çözüm - kimse bunun performansını test etti mi? örneğin, bir sınıfın bir özelliğine erişmeye kıyasla özniteliğe erişmenin ne kadar sürdüğü.
Simon Meyer

35

C # 'da öznitelikler numaralandırmalarla kullanılabilir. Ayrıntılı programlama ile bu programlama modelinin güzel bir örneği burada (Codeproject)

public enum Planet
{
   [PlanetAttr(3.303e+23, 2.4397e6)]
   Mercury,
   [PlanetAttr(4.869e+24, 6.0518e6)]
   Venus
} 

Düzenleme: bu soru yakın zamanda tekrar soruldu ve Jon Skeet tarafından cevaplandı: C # Java Java enum eşdeğeri nedir? Özel iç sınıflar C # - neden daha sık kullanılmıyor?

Edit 2: Bu yaklaşımı çok parlak bir şekilde genişleten kabul edilen cevaba bakınız !


1
Güzel! Bu sadece biraz tıknazdır, ancak aksi halde bir numaraya ekstra veri eklemek için çok kabul edilebilir bir yöntemdir. Açıkçası bu harika çözümden bahsetmenin bu kadar uzun sürdüğüne şaşırdım!
Ogre Psalm33

13

Java numaralandırmalar aslında özel bir kurucu ve yöntemler vb. Olabilir tam sınıflar iken C # numaralar sadece tamsayı olarak adlandırılır. IMO Java uygulaması çok daha üstündür.

Bir java kampından gelen c # öğrenirken bu sayfa size çok yardımcı olmalıdır. (Bağlantı, numaralandırmalarla ilgili farklılıkları gösterir (diğer şeyler için yukarı / aşağı kaydır)


1
Bağlantınız C # ve Java arasındaki benzerlikler ve farklılıklar hakkında ilginç ve kapsamlı bir genel bakış sunarken, metinde çok fazla hata var (örneğin yanlış olarak Java korumasının dahili korumalı iken C # içine eşit olduğunu belirtiyor). Bu yüzden her şeyi orada kabul
etmeyin

1
Java hayranıyım bile Java enums üstün olduğunu söyleyemem. C #, FOO = 0ORM araçlarında kullanımı daha kolay olan kolay tamsayı bildirimini destekler (hataya eğilimli ordinal()kullanım gerekmez). Ayrıca C #, özellikle birlikte kullanıldığında genellikle çok yararlı olan bitsel numaralandırmaları destekler EntityFramework. Java, tamsayılarına da bağlanabilmeleri için numaralandırmalarını genişletmelidir. Sonra üstün olurlar :)
djmj

4

Böyle bir şey bence:

public class Planets 
{
    public static readonly Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
    public static readonly Planet VENUS = new Planet(4.869e+24, 6.0518e6);
    public static readonly Planet EARTH = new Planet(5.976e+24, 6.37814e6);
    public static readonly Planet MARS = new Planet(6.421e+23, 3.3972e6);
    public static readonly Planet JUPITER = new Planet(1.9e+27,   7.1492e7);
    public static readonly Planet SATURN = new Planet(5.688e+26, 6.0268e7);
    public static readonly Planet URANUS = new Planet(8.686e+25, 2.5559e7);
    public static readonly Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);
    public static readonly Planet PLUTO = new Planet(1.27e+22,  1.137e6);
}

public class Planet
{
    public double Mass {get;private set;}
    public double Radius {get;private set;}

    Planet(double mass, double radius)
    {
        Mass = mass;
        Radius = radius;
    }

    // universal gravitational constant  (m3 kg-1 s-2)
    private static readonly double G = 6.67300E-11;

    public double SurfaceGravity()
    {
        return G * Mass / (Radius * Radius);
    }

    public double SurfaceWeight(double otherMass)
    {
        return otherMass * SurfaceGravity();
    }
}

Veya sabitleri Planetyukarıdaki gibi sınıfa birleştirin


8
Pek değil - Gezegen kurucusu özel olmalı; numaralandırmaların bir kısmı sabit bir değer kümesi olmasıdır. Değerler daha sonra Planet sınıfında da tanımlanır.
Jon Skeet

Henüz değil. 1) numaralandırıcı eksik :) 2) numaralandırmalar asla değiştirilemez. Oh ve son olarak, kodunuz tek bir sınıf için yalvarır (özel bir
kurucuya

3

Java'da bulunan özel davranışa hitap eden ilginç bir fikir daha. Aşağıdaki Enumerationtemel sınıfı buldum :

public abstract class Enumeration<T>
    where T : Enumeration<T>
{   
    protected static int nextOrdinal = 0;

    protected static readonly Dictionary<int, Enumeration<T>> byOrdinal = new Dictionary<int, Enumeration<T>>();
    protected static readonly Dictionary<string, Enumeration<T>> byName = new Dictionary<string, Enumeration<T>>();

    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<T> obj)
    {
        return obj.ordinal;
    }

    public int Ordinal
    {
        get { return ordinal; }
    }
}

Temelde bir tür parametresi var, bu yüzden sıra sayısı farklı türetilmiş numaralandırmalarda düzgün çalışacaktır. Jon Skeet'in Operatoryukarıdaki başka bir soruya verdiği yanıttan (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) daha sonra:

public class Operator : Enumeration<Operator>
{
    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<int, int, int> op;

    // Prevent other top-level types from instantiating
    private Operator(string name, Func<int, int, int> op)
        :base (name)
    {
        this.op = op;
    }

    public int Execute(int left, int right)
    {
        return op(left, right);
    }
}

Bu birkaç avantaj sağlar.

  • Sıradan destek
  • Geçiş deyimlerini mümkün kılan stringve intmümkün kılan dönüşüm
  • GetType (), türetilmiş bir Numaralandırma türünün her değeri için aynı sonucu verecektir.
  • Statik yöntemler System.Enum, aynı işlevselliğe izin vermek için temel Enumeration sınıfına eklenebilir.

3

c # için bir numaralandırma uzantısı yaptık https://github.com/simonmau/enum_ext

Sadece typesafeenum için bir uygulama, ama harika çalışıyor, bu yüzden paylaşmak için bir paket yaptık - onunla eğlenin

public sealed class Weekday : TypeSafeNameEnum<Weekday, int>
{
    public static readonly Weekday Monday = new Weekday(1, "--Monday--");
    public static readonly Weekday Tuesday = new Weekday(2, "--Tuesday--");
    public static readonly Weekday Wednesday = new Weekday(3, "--Wednesday--");
    ....

    private Weekday(int id, string name) : base(id, name)
    {
    }
}

2

Bir Java enum, numaralandırmaları OO tarzında sunmak için sözdizimsel şekerdir. Java'daki Enum sınıfını genişleten soyut sınıflardır ve her bir enum değeri, enum sınıfının statik bir son genel örnek uygulaması gibidir. Oluşturulan sınıflara bakın ve 10 değere sahip bir "Foo" enum için "Foo $ 1" ile "Foo $ 10" sınıflarının oluşturulduğunu göreceksiniz.

Ben C # bilmiyorum, sadece bu dilde bir numaralandırmanın daha çok C tarzı dillerinde geleneksel bir numaraya benzediğini tahmin edebilirim. Hızlı bir Google aramasından, ancak birden fazla değeri tutabileceklerini görüyorum, bu yüzden muhtemelen benzer bir şekilde uygulandılar, ancak Java derleyicisinin izin verdiğinden çok daha fazla kısıtlamayla.


3
Java ve C # 'daki her şey JVM veya CLR bayt kodları için sözdizimsel şekerle ilgili değil mi? :) Sadece söylüyorum
thenonhacker

2

Java numaralandırmaları, derleyici tarafından oluşturulan valueOf yöntemini kullanarak addan kolay yazım dönüşümlerine izin verir.

// Java Enum has generics smarts and allows this
Planet p = Planet.valueOf("MERCURY");

C # 'daki ham numaralandırma eşdeğeri daha ayrıntılıdır:

// C# enum - bit of hoop jumping required
Planet p = (Planet)Enum.Parse(typeof(Planet), "MERCURY");

Bununla birlikte, Kent'in engebeli yolundan giderseniz ValueOf, numaralandırma sınıfınızda kolayca bir yöntem uygulayabilirsiniz .


Java örneği, derleyici tarafından oluşturulan sentetik bir yöntem kullanıyor - jeneriklerle hiçbir ilgisi yok. Enum, jenerik bir valueOf yöntemine sahiptir, ancak Enum'ları değil, Class 'jeneriklerini kullanır.
Tom Hawtin - tackline

2

Ben C # enums sadece CLR iç sabitler, ama onları tanıdık değil sanıyorum. Java bazı sınıfları decompiled ve ben bir kez dönüştürmek Enum olmasını istediğinizi söyleyebilirim.

Java sinsi bir şey yapar. Enum sınıfına, enum değerlerine başvururken çok sayıda makro kullanarak, olabildiğince yakın bir normal sınıf olarak davranır. Java sınıfında enums kullanan bir case deyiminiz varsa, tamsayılara enum başvurularının yerini alır. Dizeye gitmeniz gerekiyorsa, her sınıfta kullandığı bir sıra ile dizinlenmiş bir dizeler dizisi oluşturur. Bokstan tasarruf ettiğinden şüpheleniyorum.

Bu kod çözücüyü indirirseniz, sınıfını nasıl oluşturduğunu ve onu nasıl entegre ettiğini göreceksiniz. Dürüst olmak gerekirse büyüleyici. Enum sınıfını kullanmıyordum çünkü bunun sadece bir dizi sabit için şişirilmiş olduğunu düşündüm. Onları C # kullanabilirsiniz sınırlı yolu daha iyi gibi.

http://members.fortunecity.com/neshkov/dj.html - Java kod çözücü


0

Java enum C # enum çok daha karmaşık ve dolayısıyla daha güçlü. Sadece başka bir derleme zamanı sözdizimsel şeker olduğundan, gerçek yaşam uygulamalarında sınırlı kullanımı göz önüne alındığında dili gerçekten dahil etmeye değer olup olmadığını merak ediyorum. Bazen, küçük bir özelliği dahil etme baskısından vazgeçmekten daha fazla şeyleri dilden uzak tutmak zordur.


2
Saygılarımla katılmıyorum. Java 1.5 enums, farklı sabit sabit öğeler kümesi ile ilgili bir soruna daha fazla OO merkezli bir çözüm uygulamak için defalarca kullandığım güçlü bir dil özelliğidir.
Ogre Mezmur33

1
Belki sen yaptın. Ancak akıllı 'anahtar' dil entegrasyonunun ötesinde, yukarıdaki örneklerde gösterildiği gibi, işlevin geri kalan kısmı C # veya Java'nın kendisinde kolayca çoğaltılabilir.
dmihailescu

@dmihailescu "Sonra Java enum C # çok daha karmaşık. Bu yüzden Java düştü ..."
Mukus

0
//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<JavaEnum> 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<T>
    private static Dictionary<Type, object> enumDictionary;
    public static SortedSet<T> RetrieveEnumValues<T>() where T : JavaEnum {
        if(enumDictionary == null) {
            enumDictionary = new Dictionary<Type, object>();
        }
        object enums;
        if(!enumDictionary.TryGetValue(typeof(T), out enums)) {
            enums = new SortedSet<T>();
            FieldInfo[] myFieldInfo = typeof(T).GetFields(BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public);
            foreach(FieldInfo f in myFieldInfo) {
                if(f.FieldType == typeof(T)) {
                    ((SortedSet<T>)enums).Add((T)f.GetValue(null));
                }
            }
            enumDictionary.Add(typeof(T), enums);
        }
        return (SortedSet<T>)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<MyEnumType>() to generate an IEnumerable set.
    public static new IEnumerable<SampleEnum> Values {
        get {
            foreach(var e in JavaEnum.RetrieveEnumValues<SampleEnum>()) {
                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<T> : SortedSet<T> where T : JavaEnum {
    // Creates an enum set containing all of the elements in the specified element type.
    public static EnumSet<T> AllOf(IEnumerable<T> values) {
        EnumSet<T> returnSet = new EnumSet<T>();
        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<T> ComplementOf(IEnumerable<T> values, EnumSet<T> set) {
        EnumSet<T> returnSet = new EnumSet<T>();
        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<T> Range(IEnumerable<T> values, T from, T to) {
        EnumSet<T> returnSet = new EnumSet<T>();
        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<T> Of(params T[] setItems) {
        EnumSet<T> returnSet = new EnumSet<T>();
        foreach(T item in setItems) {
            returnSet.Add(item);
        }
        return returnSet;
    }

    // Creates an empty enum set with the specified element type.
    public static EnumSet<T> NoneOf() {
        return new EnumSet<T>();
    }

    // Returns a copy of the set passed in.
    public static EnumSet<T> CopyOf(EnumSet<T> set) {
        EnumSet<T> returnSet = new EnumSet<T>();
        returnSet.Add(set);
        return returnSet;
    }

    // Adds a set to an existing set.
    public void Add(EnumSet<T> enumSet) {
        foreach(T item in enumSet) {
            this.Add(item);
        }
    }

    // Removes a set from an existing set.
    public void Remove(EnumSet<T> enumSet) {
        foreach(T item in enumSet) {
            this.Remove(item);
        }
    }
}

0

Ayrıca, her bir enum türü için, her bir enum değeri için gelişmiş veriler içeren bir örneği tutan bir yardımcı sınıf kullanabilirsiniz.

public enum Planet
{
    MERCURY,
    VENUS
}

public class PlanetUtil
{
    private static readonly IDictionary<Planet, PlanetUtil> PLANETS = new Dictionary<Planet, PlanetUtil();

    static PlanetUtil()
    {
        PlanetUtil.PLANETS.Add(Planet.MERCURY, new PlanetUtil(3.303e+23, 2.4397e6));
        PlanetUtil.PLANETS.Add(Planet.VENUS, new PlanetUtil(4.869e+24, 6.0518e6));
    }

    public static PlanetUtil GetUtil(Planet planet)
    {
        return PlanetUtil.PLANETS[planet];
    }

    private readonly double radius;
    private readonly double mass;

    public PlanetUtil(double radius, double mass)
    {
        this.radius = radius;
        this.mass = mass;
    }

    // getter
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.