Reproduce Java enum in C #

This article is the 11th day article of StudioZ Tech Advent Calendar 2019.

Introduction

I started using Unity about 5 years ago and switched from Java to C #. Since it is a language with many similarities, I was able to use it with almost no discomfort, but the only problem was the enum specifications. So I wondered if I could reproduce the Java enum in C #.

Java enum characteristics and implementation method

--The enumerator has an instance of the enum. ――You can meet it by using the class normally --Cannot create an instance from the outside --It can be handled by making the constructor private. --Enumeration. Can be accessed by enumeration --If you manage the instance of the enumerator in the static field, it will be accessible. --You cannot define an enumerator with the same name --A field with the same name cannot be defined, so it will be satisfied when managing with a static field.

If you code the conditions so far, it will look like this

    public class EnumSample {
        public static EnumSample Enum1 = new EnumSample();
        public static EnumSample Enum2 = new EnumSample();
        public static EnumSample Enum3 = new EnumSample();
        public static EnumSample Enum4 = new EnumSample();
        //Cannot create an instance from the outside
        private EnumSample() {}
    }

--The enumerator can have unique values --Receive the value in the constructor and have it in the field --However, you cannot statically check for duplicates (you can check at runtime).

    public class EnumSample2 {
        public static EnumSample2 Enum1 = new EnumSample2( 1 );
        public static EnumSample2 Enum2 = new EnumSample2( 2 );
        public static EnumSample2 Enum3 = new EnumSample2( 3 );
        public static EnumSample2 Enum4 = new EnumSample2( 4 );
    
        public int Num;
        //Cannot create an instance from the outside
        private EnumSample2( int num ) {
            Num = num;
            //If you want to check for duplicates, do it around here
            //It seems easy to pack it in a dictionary and check it with the Contains Key
        }
    }

--Methods can be implemented for each instance --Make the enumerator class an abstract class and inherit the class for each enumerator to implement the method --Abstract if you want to make it mandatory for each enumerator, virtual if you want to define the default behavior --Duplicate processing can be eliminated by implementing the processing that you want to standardize between enumerators on the parent class side and the processing that you want to differentiate on the child class side. --The enumeration can implement the interface --Just declare the interface to be implemented in the enum

    //Drop item interface
    public interface IDropItem {
        string Name { get; }
        int Price { get; }
        string Description { get; }
    }
    
    //Enumeration of weapons that can be treated as drop items
    public abstract class Weapon : IDropItem {
        public static Weapon Sword = new WeaponSword();
        private class WeaponSword : Weapon {
            //Even if the constructor is public, the class itself is private, so it cannot be instantiated from the outside.
            public WeaponSword() {}
            public override string Name { get { return "sword"; } }
            public override int Price { get { return 100; } }
            public override string Description { get { return "A nice explanation"; } }
            public override void Attack() {
                base.Slash();
            }
        }

        public static Weapon Spear = new WeaponSpear();
        private class WeaponSpear : Weapon {
            public WeaponSpear() {}
            public override string Name { get { return "spear"; } }
            public override int Price { get { return 50; } }
            public override string Description { get { return "Explanation like that"; } }
            public override void Attack() {
                base.Pierce();
            }
        }

        public static Weapon Club = new WeaponClub();
        private class WeaponClub : Weapon {
            public WeaponClub() {}
            public override string Name { get { return "club"; } }
            public override int Price { get { return 10; } }
            public override string Description { get { return "Very strange explanation"; } }
            // Attack()Implementation is optional
        }

        protected Weapon() {}
    
        //Be sure to define the name, price, and description with an enumerator
        public abstract string Name { get; }
        public abstract int Price { get; }
        public abstract string Description { get; }

        //Implementation of attack processing can be omitted
        public virtual void Attack() {
            //If not overridden, the process of hitting as the default
            Strike();
        }

        //Properties and methods declared as protected can be accessed from the enumerator side
        protected void Slash() {
            //Processing weapons to cut
        }

        protected void Pierce() {
            //Handling of stabbing weapons
        }

        protected void Strike() {
            //Handling of beating weapons
        }

    }

What you can't do in C

--Use enumerator as a switch condition --You can't use enumerators that are actually classes, because you can only use constants in cases ――However, since you can implement the process on the enumerator side, I think that you basically do not need to use switch.

in conclusion

It may seem awkward at first glance, but using Java-style enums makes it easier to achieve polymorphism. If you have a chance, please give it a try

reference

Java constants are Enums! I will tell you how to use Enums and how to think about them

Recommended Posts

Reproduce Java enum in C #
Enum Strategy pattern in Java
[Java] enum
Read Java properties file in C #
Java, JavaScript, C # (difference in assignment)
Partization in Java
Changes in Java 11
Rock-paper-scissors in Java
Pi in Java
Java Direction in C ++ Design and Evolution
FizzBuzz in Java
Java to C and C to Java in Android Studio
Differences in writing Java, C # and Javascript classes
[java] sort in list
Read JSON in Java
Interpreter implementation in Java
Make Blackjack in Java
Rock-paper-scissors app in Java
Java Enum utilization example
Constraint programming in Java
Put java8 in centos7
Combine arrays in Java
"Hello World" in Java
Callable Interface in Java
Comments in Java source
Azure functions in java
Format XML in Java
Simple htmlspecialchars in Java
Boyer-Moore implementation in Java
Hello World in Java
Use OpenCV in Java
Enum reverse map Java
webApi memorandum in java
Type determination in Java
Ping commands in Java
Various threads in java
Zabbix API in Java
ASCII art in Java
Compare Lists in Java
POST JSON in Java
Express failure in Java
Create JSON in Java
Date manipulation in Java 8
What's new in Java 8
[Java] About enum type
Use PreparedStatement in Java
What's new in Java 9,10,11
Parallel execution in Java
Initializing HashMap in Java
Organize builds in C ++ / Java and Win / Linux combinations
Quickly implement a singleton with an enum in Java
[.net, Java integration] Nger that executes .jar in C # .net
Reverse Enum constants from strings and values in Java
Try using RocksDB in Java
Read binary files in Java 1
Solving in Ruby, Perl and Java AtCoder ABC 113 C Reference
Avoid Yubaba's error in Java
Get EXIF information in Java
Save Java PDF in Excel
[Neta] Sleep Sort in Java
Edit ini in Java: ini4j