Is it possible to mimic this java enum code in c#

c# enum polymorphism
c# partial enum
enum class c#
c# override enum
c# advanced enum
c# inherit enum
c# enum alternative
c# enum string

Is it possible to copy this functionality of offering an abstract method in an enum that inner enum constants must override and provide functionality to?

public enum Logic {
    PAY_DAY {
        @Override
        public void acceptPlayer(Player player) {
            // Perform logic
        }
    },
    COLLECT_CASH {
        @Override
        public void acceptPlayer(Player player) {
            // Perform logic
        }
    }
    ,
    ETC_ETC {
        @Override
        public void acceptPlayer(Player player) {
            // Perform logic
        }
    };

    public abstract void acceptPlayer(Player player);
}

If it can't:: Could you provide a way which I can implement lots of specific logic in a similar manner?

Edit :: I know that enums in C# are not really 'objects' like they are in Java, but I wish to perform similar logic.

Edit :: To clarify, I do not want to provide concrete classes for each specific bit of logic. IE, creating an interface acceptPlayer and creating many new classes is not appropiate

Here's one option - not using enums, but something similar-ish...

public abstract class Logic
{
    public static readonly Logic PayDay = new PayDayImpl();
    public static readonly Logic CollectCash = new CollectCashImpl();
    public static readonly Logic EtcEtc = new EtcEtcImpl();

    // Prevent other classes from subclassing
    private Logic() {}

    public abstract void AcceptPlayer(Player player);

    private class PayDayImpl : Logic
    {
        public override void AcceptPlayer(Player player)
        {
            // Perform logic
        }
    }

    private class CollectCashImpl : Logic
    {
        public override void AcceptPlayer(Player player)
        {
            // Perform logic
        }
    }

    private class EtcEtcImpl : Logic
    {
        public override void AcceptPlayer(Player player)
        {
            // Perform logic
        }
    }
}

You say that you don't want to provide a concrete class for each bit of logic - but that's basically what you'd be doing in Java anyway, it's just that the class would be slightly hidden from you.

Here's an alternative approach using delegates for the varying behaviour:

public sealed class Logic
{
    public static readonly Logic PayDay = new Logic(PayDayAccept);
    public static readonly Logic CollectCash = new Logic(CollectCashAccept);
    public static readonly Logic EtcEtc = new Logic(player => {
        // An alternative using lambdas...
    });

    private readonly Action<Player> accept;

    private Logic(Action<Player> accept)
    {
        this.accept = accept;
    }

    public void AcceptPlayer(Player player)
    {
        accept(player);
    }

    private static void PayDayAccept(Player player)
    {
        // Logic here
    }

    private static void CollectCashAccept(Player player)
    {
        // Logic here
    }
}

In both cases, you still get a fixed set of values - but you won't be able to switch on them. You could potentially have a separate "real" enum, but that would be a bit messy.

Enhanced enums in C#, They're really not very object oriented: they're not type-safe (you can cast from one project last year, I've been increasingly fed up with C#'s enums. specify the value in source code to avoid the problems described in Java earlier. I wrote a class that uses Generics and Reflection to emulate most of the� Java C#; public enum Simple { FOO, BAR} public enum Simple { FOO, BAR} More complex enums in Java unfortunately have exceedingly complex equivalents in C#:

If you don't want to use interfaces and a class hierarchy, you could use delegates, something like :

public class Player{}

public static class Logic
{
    public static readonly Action<Player> PAY_DAY = p => Console.WriteLine( "Pay day : " + p.ToString());

    public static readonly Action<Player> COLLECT_CASH = p=> Console.WriteLine(p.ToString ());

    public static void AcceptPlayer( this Action<Player> PlayerAction, Player ActingPlayer )
    {
        PlayerAction(ActingPlayer);
    }
}

class MainClass
{
    public static void Main (string[] args)
    {
        var player = new Player();

        Logic.PAY_DAY.AcceptPlayer( player );
    }
}

Enhancing C# Enums, The enum above describes a set of possible values that a variable of type Here's the code of the base class that we will use to implement the enhanced enums . In this article, we saw how to use classes to simulate the behavior of enums you are confronted with more of those cases since you use both Java and C#. Although C# and Java are very similar languages, there are a few things that differ greatly. I was porting some Java code to C# and ran into Java’s crazy enum type. The C# enum type, like most languages that support enums, is a very simple way to define a variable type which can only have discrete, categorical values.

I like the advantages of Java enums and wanted to try to simulate them. I have looked at many posts here and could not find a simple way to do this so I came up with the following. I am not a professional so please forgive me for any stupid mistakes. This, I beleive, provides almost all of the functionality to a Java enum (I did not write a clone method).

Also, I apologize for the length of this post.

This is the abstract class:

#region + Using Directives
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using TestEnum;

#endregion

namespace TestEnum
{
    public abstract class ACsEnum<T, U, V> :
        IComparable<ACsEnum<T, U, V>>
        where T : ACsEnum<T, U, V>
    {
        static ACsEnum()
        {
            // the static constructor causes
            // early creation of the object
            Count = 0;
        }

        // constructor
        protected ACsEnum(Enum m, V v)
        {
            Enum = m;
            Value = v;
            Ordinal = Count++;
        }

    #region Admin Private fields

        // the list of members
        protected static readonly List<T> members = new List<T>();

    #endregion

    #region Admin Public Properties

        // the enum associated with this class
        public Enum Enum { get; }

        // number of members
        public static int Count { get; private set; }

        // ordinal number of this member (zero based)
        public int Ordinal { get; }

        // a name of this member
        public string Name => ToString();

        // the value attached to the enum
        public U Amount => (U) (IConvertible) Enum;

        // the value of this member - this value is
        // returned from the implicit conversion
        public V Value { get; }

    #endregion

    #region Admin Operator

        public static implicit operator V (ACsEnum<T, U, V> m)
        {
            return m.Value;
        }

    #endregion

    #region Admin Functions

        // compare
        public int CompareTo(ACsEnum<T, U, V> other)
        {
            if (other.GetType() != typeof(T)) { return -1; }

            return Ordinal.CompareTo(other.Ordinal);
        }

        // determine if the name provided is a member
        public static bool IsMember(string name, bool caseSensitive)
        {
            return Find(name, caseSensitive) != null;
        }

        // finds and returns a member
        public static T Find (string name, bool caseSensitive = false)
        {
            if (caseSensitive)
            {
                return members.Find(s => s.ToString().Equals(name));
            }
            else
            {
                return members.Find(s => s.ToString().ToLower().Equals(name.ToLower()));
            }
        }

        // allow enumeration over the members
        public static IEnumerable Members()
        {
            foreach (T m in members)
            {
                yield return m;
            }
        }

        // get the members as an array
        public static T[] Values()
        {
            return members.ToArray();
        }

        // same as Find but throws an exception 
        public static T ValueOf(string name)
        {
            T m = Find(name, true);

            if (m != null) return m;

            throw new InvalidEnumArgumentException();
        }

    #endregion

    #region Admin Overrides

        public override bool Equals(object obj)
        {
            if (obj != null && obj.GetType() != typeof(T)) return false;

            return ((T) obj).Ordinal == Ordinal ;
        }

    #endregion
    }
}

This is an extension method to help with enum's:

namespace TestEnum
{
    // special enum extension that gets the value of an enum
    // 
    public static class EnumEx
    {
        public static dynamic Value(this Enum e)
        {
            switch (e.GetTypeCode())
            {
            case TypeCode.Byte:
                {
                    return (byte) (IConvertible) e;
                }
            case TypeCode.Int16:
                {
                    return (short) (IConvertible) e;
                }
            case TypeCode.Int32:
                {
                    return (int) (IConvertible) e;
                }
            case TypeCode.Int64:
                {
                    return (long) (IConvertible) e;
                }
            case TypeCode.UInt16:
                {
                    return (ushort) (IConvertible) e;
                }
            case TypeCode.UInt32:
                {
                    return (uint) (IConvertible) e;
                }
            case TypeCode.UInt64:
                {
                    return (ulong) (IConvertible) e;
                }
            case TypeCode.SByte:
                {
                    return (sbyte) (IConvertible) e;
                }
            }

            return 0;
        }
    }
}

This is the actual "enum" class:

namespace TestEnum
{
    public class Planet : ACsEnum<Planet, byte, double>
    {
    #region Base enum

        // this holds the position from the sun
        public enum planet : byte
        {
            MERCURY = 1,
            VENUS   = 2,
            EARTH   = 3,
            MARS    = 4,
            JUPITER = 5,
            SATURN  = 6,
            URANUS  = 7,
            NEPTUNE = 8,
            PLUTO   = 9
        }

    #endregion

    #region ctror

        // planet enum, mass, radius, orbital period (earth days)
        private Planet(   planet p, double m, double r, double v) : base(p, v)
        {
            Mass = m;
            Radius = r;

            members.Add(this);
        }

    #endregion

    #region enum specific Properties

        public double Mass { get;  }
        public double Radius { get;  }

    #endregion

    #region enum specific Functions

        public static double G = 6.67300E-11;

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

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

    #endregion

    #region Overrides

        public override string ToString() => Enum.ToString();

    #endregion

    #region Members

        //                                                          enum      mass            radius       "year"
        public static readonly Planet MERCURY   = new Planet(planet.MERCURY, 3.303e+23     , 2.4397e6   ,     88.0);
        public static readonly Planet VENUS     = new Planet(planet.VENUS  , 4.869e+24     , 6.0518e6   ,    224.7);
        public static readonly Planet EARTH     = new Planet(planet.EARTH  , 5.976e+24     , 6.37814e6  ,    365.2);
        public static readonly Planet MARS      = new Planet(planet.MARS   , 6.421e+23     , 3.3972e6   ,    687.0);
        public static readonly Planet JUPITER   = new Planet(planet.JUPITER, 1.9e+27       , 7.1492e7   ,   4331.0);
        public static readonly Planet SATURN    = new Planet(planet.SATURN , 5.688e+26     , 6.0268e7   ,  10747.0);
        public static readonly Planet URANUS    = new Planet(planet.NEPTUNE, 8.686e+25     , 2.5559e7   ,  30589.0);
        public static readonly Planet NEPTUNE   = new Planet(planet.URANUS , 1.024e+26     , 2.4746e7   ,  59800.0);
        public static readonly Planet PLUTO     = new Planet(planet.PLUTO  , 11.30900e+22  , 1.187e6    ,  90560.0);

    #endregion

    }
}

Lastly, here is the usage example:

using System;
using static TestEnum.Planet;

namespace TestEnum
{
    class Program
    {

        static void Main(string[] args)
        {
            Program p = new Program();

            p.EnumTest();

            Console.WriteLine("\n\nWaiting ...:  ");
            Console.ReadKey();
        }

        private void EnumTest()
        {

            // test:
            // each admin property: count, ordinal, value, name
            // each unique property: APlanet, Mass, Radius, G
            // implicit operator
            // admin functions: 
            // admin overrides:
            // unique properties
            // unique functions

            Console.WriteLine("\nadmin properties\n");
            Console.WriteLine("count     | " + Planet.Count + "  (== 9)");
            Console.WriteLine("ordinal   | " + MERCURY.Ordinal + "  (== 0)");
            Console.WriteLine("name      | " + MERCURY.Name + " (== MERCURY)");
            Console.WriteLine("value     | " + MERCURY.Value + " (== 88 Mercury year)");

            double x = EARTH;

            Console.WriteLine("\nadmin Operator\n");
            Console.WriteLine("Year      | " + x + "  (== 365.2 year)");

            Console.WriteLine("\nadmin functions\n");
            Console.WriteLine("Compare to| " + MERCURY.CompareTo(EARTH) + "  (== -1)");
            Console.WriteLine("IsMember  | " + Planet.IsMember("EARTH", true) + "  (== true)");
            Console.WriteLine("Find      | " + Planet.Find("EARTH", true).Name + "  (== EARTH)");
            Console.WriteLine("ValueOf   | " + Planet.ValueOf("EARTH").Name + "  (== EARTH)");
            Console.WriteLine("Equals    | " + EARTH.Equals(MERCURY) + " (== false => EARTH != MERCURY)");

            Console.WriteLine("\n\nunique admin\n");
            Console.WriteLine("G         | " + Planet.G);

            Console.WriteLine("\nunique properties\n");
            Console.WriteLine("Enum      | " + MERCURY.Enum);
            Console.WriteLine("Mass      | " + MERCURY.Mass);
            Console.WriteLine("Radius    | " + MERCURY.Radius);
            Console.WriteLine("amount    | " + MERCURY.Amount + "  (== 1 MERCURY first planet)");

            Console.WriteLine("\n\nunique functions");

            // typical Java enum usage example

            double earthWeight = 175; // lbs

            double mass = earthWeight / EARTH.SurfaceGravity();

            Console.WriteLine("\ncalc weight via foreach\n");

            foreach (Planet p in Planet.Members())
            {
                Console.WriteLine("Your weight on {0} is {1:F5}",
                    p.Name, p.SurfaceWeight(mass));
            }

            // end, typical Java enum usage example

            // test Values

            Planet[] planets = Planet.Values();

            Console.WriteLine("\ncalc weight  via array\n");

            foreach (Planet p in planets)
            {
                Console.WriteLine("Your weight on {0} is {1:F5}",
                    p.Name, p.SurfaceWeight(mass));
            }

            // test switch
            Planet planet = PLUTO;

            Console.WriteLine("\nuse switch - looking for PLUTO\n");

            switch (planet.Enum)
            {
            case Planet.planet.EARTH:
                {
                    Console.WriteLine("found EARTH\n");
                    break;
                }
            case Planet.planet.JUPITER:
                {
                    Console.WriteLine("found JUPITER\n");
                    break;
                }
            case Planet.planet.PLUTO:
                {
                    Console.WriteLine("found PLUTO\n");
                    break;
                }
            }

            // these will use implicit value
            Console.WriteLine("\ntest comparison checks\n");
            if (EARTH == EARTH)
            {
                Console.WriteLine("\npassed - EARTH == EARTH\n");
            }

            if (MERCURY < EARTH)
            {
                Console.WriteLine("passed - MERCURY < EARTH\n");
            }

            if (PLUTO > EARTH)
            {
                Console.WriteLine("passed - PLUTO > EARTH\n");
            }

            // test enum extension

            Console.WriteLine("\nbonus - enum extension\n");
            Console.WriteLine("PLUTO AsShort| " + Planet.planet.PLUTO.Value() + "  (9th planet)");


            // test ValueOf failure
            Console.WriteLine("\n\nValueOf that fails\n");
            try
            {
                planet = Planet.ValueOf("xxx");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

        }
    }
}

I hope this helps anyone who wants to provide added features to enum's and maybe this will help someone convert their program from Java to C#

Polymorphic enums in C#, implementation revealed, How can we implement a polymorphic enum to mimic the Java ones ? In order to be able to write such code, here is what I can do : First, the� C# enum keyword represents an enum or enumeration. An enum is a constant numbers represented by a value. Here is a list of C# enum code samples in C# and .NET.

In c#, you do this with classes, not enums. Create a base class with the virtual method you want to override.

Each member of the Java enum will be a sub-class with the implementation you want.

Finally, create a read-only static field in the base class for each enum member, initializing it with an instance of the sub-class for that enum value.

Proposal: Class-level enum (as in Java) � Issue #274 � dotnet , Of course, we can always declare a new class to simulate enums but this feature to host and review code, manage projects, and build software together. Microsoft would not be able to implement the same construct in C#. Then you can use integer values in your xml file and they will be mapped to the enum automagically. Personally, I prefer using enums in cases like this. Even if the items in the enum could increase over time, I prefer using enums. In fact such enums are code generated from the database, so in code you don't work with Ids (much more readable).

Extending the answer by Jon Skeet I found a slightly other approach that even allows you individual behavior / data with an enum similar structure. It is maybe not a real answer to the question, because it does not fulfill:

Edit :: To clarify, I do not want to provide concrete classes for each specific bit of logic. IE, creating an interface acceptPlayer and creating many new classes is not appropiate

The following construct together with C# 7 gives a very enum like syntax:

public abstract class Logic
{
    private Logic() { }

    public abstract void acceptPlayer(Player player);

    public sealed class PayDay : Logic
    {
        public PayDay(DateTime timeOfPayment)
        {
            TimeOfPayment = timeOfPayment;
        }

        public DateTime TimeOfPayment { get; }

        public override void acceptPlayer(Player player)
        {
            // Perform logic
        }
    }

    public sealed class CollectCash : Logic
    {
        public CollectCash(int amountOfMoney)
        {
            AmountOfMoney = amountOfMoney;
        }

        public int AmountOfMoney { get; }

        public override void acceptPlayer(Player player)
        {
            // Perform logic
        }
    }

    public sealed class EtcEtc : Logic
    {
        public override void acceptPlayer(Player player)
        {
            // Perform logic
        }
    };
}

The private constructor of the abstract Logic class and the sealed implementations guarantee that there is only a well defined set of options that are all part of the scope of the Logic class.

Creation looks somewhat unusual:

Logic logic = new Logic.PayDay(DateTime.Now);

But together with C# 7's Pattern Matching it even starts to feel like an enum:

switch (logic)
{
    case Logic.PayDay payday:
        var timeOfPayment = payday.TimeOfPayment;
        // ...
        break;
    case Logic.CollectCash collectCash:
        // ...
        break;
    // ...
}

And also other test logic is quite readable:

if (logic is Logic.EtcEtc)
{
    // ...
}

Or if you need the casted instance:

if (logic is Logic.EtcEtc etcEtc)
{
    // ...
}

Enum Tricks: Dynamic Enums, Java enums by definition are immutable and must be defined in code. In this article I Motivation. There are 3 ways to use enums: This class mimics functionality of Enum but it is regular class, so it can be inherited. A static� All enums implicitly extend java.lang.Enum class. As a class can only extend one parent in Java, so an enum cannot extend anything else. toString() method is overridden in java.lang.Enum class,which returns enum constant name. enum can implement many interfaces. values(), ordinal() and valueOf() methods : These methods are present inside java

Java Enums, Java Enums. An enum is a special "class" that represents a group of constants ( unchangeable variables, like final variables). To create an enum , use the enum� How is it possible to ensure that the enum gets some kind of null value if it is not set, I don't want it defaulting to the first value in the enum. Best practice (as advised by Code Analysis) is to always have a default value in your enums, which represent an unset value.

Comparison of C Sharp and Java, This article compares two programming languages: C# with Java. While the focus of this article Code blocks or methods that use the pointers must be marked with the unsafe keyword to be able to use pointers, Java language designers have avoided new keywords as much as possible, preferring instead to introduce � In this article, we will see what Java enums are, what problems they solve and how some of the design patterns they can be used in practice. The enum keyword was introduced in Java 5. It denotes a special type of class that always extends the java.lang.Enum class. For the official documentation on their usage have a look at the documentation.

Enum in Java with int conversion – Dan Clarke, Java has the most robust implementation of the 'enum pattern' of any The user can't change it, and we don't need any code to run on access; so I think a getter� Enum members are named and scoped in a manner exactly analogous to fields within classes. The scope of an enum member is the body of its containing enum type. Within that scope, enum members can be referred to by their simple name. From all other code, the name of an enum member must be qualified with the name of its enum type.

Comments
  • This is not possible in C# enums - there is no support for such a feature.
  • And instead of explaining what you don't want, tell us what you do to achieve.
  • You could create an Action factory that you pass it a value and it gives you back a related Action to execute.
  • I did see this as an option, but it's still providing concrete classes really. Can something be done with delegates perhaps?
  • Hey I feel pretty cool, I thought of the same solution as Jon Skeet (and I hadn't even seen his first). I am DA MAN.
  • @AlanFoster: The enum solution in Java is "still providing concrete classes really" - so why is it okay for you in Java but not in C#? Note that I've provided two bits of code here - the second does use delegates.
  • @JonSkeet ah, the second looks much cleaner. Any reason why you wouldn't use a struct here and be closer to enums?
  • @nawfal: Right, yes. Enums in C# aren't really "safe" in that you can just cast from any value of the underlying type to the enum. They're named numbers rather than a set of valid values.
  • Can I ask what the name of this is? How is it that player.AcceptPlayer is now a valid method for player, when you declared it in a different class?
  • It's an extension method (actually I have edited it so that it works more like your question) : msdn.microsoft.com/en-us/library/bb383977.aspx. The this keyword on the first argument means that any instance of the Action<Player> type will have the AcceptPlayer method associated with it.