C# vs Java Enum (for those new to C#) - c#

I've been programming in Java for a while and just got thrown onto a project that's written entirely in C#. I'm trying to come up to speed in C#, and noticed enums used in several places in my new project, but at first glance, C#'s enums seem to be more simplistic than the Java 1.5+ implementation. Can anyone enumerate the differences between C# and Java enums, and how to overcome the differences? (I don't want to start a language flame war, I just want to know how to do some things in C# that I used to do in Java). For example, could someone post a C# counterpart to Sun's famous Planet enum example?
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 ...]

In C# you can define extension methods on enums, and this makes up for some of the missing functionality.
You can define Planet as an enum and also have extension methods equivalent to surfaceGravity() and surfaceWeight().
I have used custom attributes as suggested by Mikhail, but the same could be achieved using a Dictionary.
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
}

Enumerations in the CLR are simply named constants. The underlying type must be integral. In Java an enumeration is more like a named instance of a type. That type can be quite complex and - as your example shows - contain multiple fields of various types.
To port the example to C# I would just change the enum to an immutable class and expose static readonly instances of that class:
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;
}
}

In C# attributes can be used with enums. Good example of this programming pattern with detailed description is here (Codeproject)
public enum Planet
{
[PlanetAttr(3.303e+23, 2.4397e6)]
Mercury,
[PlanetAttr(4.869e+24, 6.0518e6)]
Venus
}
Edit: this question has been recently asked again and answered by Jon Skeet: What's the equivalent of Java's enum in C#?
Private inner classes in C# - why aren't they used more often?
Edit 2: see the accepted answer which extends this approach in a very brilliant way!

Java enums are actually full classes which can have a private constructor and methods etc, whereas C# enums are just named integers. IMO Java's implementation is far superior.
This page should help you a lot while learning c# coming from a java camp. (The link points to the differences about enums (scroll up / down for other things)

Something like this I think:
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();
}
}
Or combine the constants into the Planet class as above

we have just made an enum extension for c#
https://github.com/simonmau/enum_ext
It's just a implementation for the typesafeenum, but it works great so we made a package to share - have fun with it
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)
{
}
}

Here's another interesting idea which caters for the custom behaviour available in Java. I came up with the following Enumeration base class:
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; }
}
}
It's got a type parameter basically just so the ordinal count will work properly across different derived enumerations. Jon Skeet's Operator example from his answer to another question (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) above then becomes:
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);
}
}
This gives a few advantages.
Ordinal support
Conversion to string and int which makes switch statements feasible
GetType() will give the same result for each of the values of a derived Enumeration type.
The Static methods from System.Enum can be added to the base Enumeration class to allow the same functionality.

A Java enum is syntactic sugar to present enumerations in an OO manner. They're abstract classes extending the Enum class in Java, and each enum value is like a static final public instance implementation of the enum class. Look at the generated classes, and for an enum "Foo" with 10 values, you'll see "Foo$1" through "Foo$10" classes generated.
I don't know C# though, I can only speculate that an enum in that language is more like a traditional enum in C style languages. I see from a quick Google search that they can hold multiple values however, so they are probably implemented in a similar manner, but with far more restrictions than what the Java compiler allows.

Java enums allow easy typesafe conversions from the name using the compiler-generated valueOf method, i.e.
// Java Enum has generics smarts and allows this
Planet p = Planet.valueOf("MERCURY");
The equivalent for a raw enum in C# is more verbose:
// C# enum - bit of hoop jumping required
Planet p = (Planet)Enum.Parse(typeof(Planet), "MERCURY");
However, if you go down the route sugegsted by Kent, you can easily implement a ValueOf method in your enum class.

I suspect enums in C# are just constants internal to the CLR, but not that familiar with them. I have decompiled some classes in Java and I can tell you want Enums are once you convert.
Java does something sneaky. It treats the enum class as a a normal class with, as close as I can figure, using lots of macros when referencing the enum values. If you have a case statement in a Java class that uses enums, it replaces the enum references to integers. If you need to go to string, it creates an array of strings indexed by an ordinal that it uses in each class. I suspect to save on boxing.
If you download this decompiler you will get to see how it creates its class an integrates it. Rather fascinating to be honest. I used to not use the enum class because I thought it was to bloated for just an array of constants. I like it better than the limited way you can use them in C#.
http://members.fortunecity.com/neshkov/dj.html -- Java decompiler

The enum in Java is much more complex than C# enum and hence more powerful.
Since it is just another compile time syntactical sugar I'm wondering if it was really worth having included the language given its limited usage in real life applications.
Sometimes it's harder keeping stuff out of the language than giving up to the pressure to include a minor feature.

//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);
}
}
}

You could also use a utility class for each enum type which holds a instance with advanced data for each enum value.
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
}

Related

Private delegates in C#

I'm working with a class that contains several variants of a private method. Currently, I'm using an enum to select the appropriate one within an exposed method like so.
public class MyClass
{
public enum MyEnum { Type1, Type2, Type3, Type4 };
private MyEnum _type;
public MyClass(MyEnum type)
{
Type = type;
}
public MyEnum Type
{
get { return _type; }
set { _type = value; }
}
public int Function(int x, int y)
{
switch(_type)
{
case MyEnum.Type1:
return Function1(x,y);
case MyEnum.Type2:
return Function2(x,y);
case MyEnum.Type3:
return Function3(x, y);
case MyEnum.Type4:
return Function4(x, y);
}
}
private int Function1(int x, int y)
{
// function variant 1
}
private int Function2(int x, int y)
{
// function variant 2
}
private int Function3(int x, int y)
{
// function variant 3
}
private int Function4(int x, int y)
{
// function variant 4
}
}
This works fine but I'm wondering if I'd be better off going with a private delegate which is updated whenever the enum changes. Especially since, in this case, the public method will be called much more frequently than the enum setter.
public class MyClass
{
public enum MyEnum { Type1, Type2, Type3, Type4 };
private Func<int, int, int> _function;
private MyEnum _type;
public MyClass(MyEnum type)
{
Type = type;
}
public MyEnum Type
{
get { return _type; }
set
{
_type = value;
OnTypeChange();
}
}
private void OnTypeChange()
{
switch (_type)
{
case MyEnum.Type1:
_function = Function1;
return;
case MyEnum.Type2:
_function = Function2;
return;
case MyEnum.Type3:
_function = Function3;
return;
case MyEnum.Type4:
_function = Function4;
return;
}
}
public int Function(int x, int y)
{
return _function(x, y);
}
private int Function1(int x, int y)
{
// function variant 1
}
private int Function2(int x, int y)
{
// function variant 2
}
private int Function3(int x, int y)
{
// function variant 3
}
private int Function4(int x, int y)
{
// function variant 4
}
}
I suppose I'm just looking for some conventional wisdom on the subject. How is this sort of thing typically handled out in the wild?
Your second option is technically better, because you don't have to go through the switch every time the public method is called.
The first is a bit more readable.
In all reality though, switching behavior on an enum is a decent sized red flag. Usually you would subclass MyClass and use polymorphism to get the desired behavior. I would definitely consider doing so in your case. "In the wild", that's probably the approach I would use.
Along the lines of what BradleyDotNET is getting at, there are ways to adhere to the open/closed principle along with good design practices leveraging the power of .NET. Here is a simple example of how you could implement what you are asking for, have it be easily extensible, and easily maintainable.
public enum MyEnum
{
Value1, Value2, Value3, Value4
}
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class MyClassHandlerAttribute : Attribute
{
public MyEnum Handles { get; private set; }
public MyClassHandlerAttribute(MyEnum handles) { Handles = handles; }
}
public abstract class MyClass
{
public abstract int Function(int x, int y);
}
public static class MyClassFactory
{
public static MyClass Create(MyEnum type)
{
var handler = Assembly.GetExecutingAssembly().GetTypes().Where(t =>
{
var a = t.GetCustomAttribute<MyClassHandlerAttribute>();
if (a != null && a.Handles == type)
return true;
return false;
}).FirstOrDefault();
if (handler != null)
return Activator.CreateInstance(handler) as MyClass;
return null;
}
}
[MyClassHandler(MyEnum.Value1)]
public sealed class MyClassType1 : MyClass
{
public int Function(int x, int y) { return x * y; }
}
[MyClassHandler(MyEnum.Value2)]
public sealed class MyClassType2 : MyClass
{
public int Function(int x, int y) { return x * x + y; }
}
You could even make the subclasses have internal default constructors so nobody outside of your assembly creates types of any class or subclass.
If you want a walk-through of the code, you have the MyEnum type (which could be moved inside the MyClass, but would violate OCP if you ever had to add to it), so its defined outside the class.
You then have a custom attribute MyClassHandlerAttribute so you can mark handlers to be "auto-discovered" by the factory class.
Then you have the factory which uses type inspection to load handlers for your enum. Its pretty simple, it looks at all the types in the assembly with the custom attribute and if it handles that enum value, it returns it. (Somebody probably has a slicker LINQ query for this but I did this quick)
And then you have your sub classes, easily maintainable, no code smell, simple short code units.
If you really don't want to subclass, another alternative is to use a lookup table (LUT):
delegate int FunctionDelegate(int x, int y);
enum FunctionName { Function1, Function2, Function3 };
class FunctionItem
{
public FunctionItem(FunctionName functionName, FunctionDelegate del)
{
FunctionName = functionName;
Delegate = del;
}
public FunctionName FunctionName
{
private set;
get;
}
public FunctionDelegate Delegate
{
private set;
get;
}
}
static readonly FunctionItem[] LUT = new FunctionItem[]
{
new FunctionItem(FunctionName.Function1, Method1),
new FunctionItem(FunctionName.Function2, Method2),
new FunctionItem(FunctionName.Function3, Method3)
};
// Fragment of lookup:
FunctionItem f = LUT[function];
Debug.Assert(f.Function == function);
int result = f.Delegate(...); // Invoke delegate
Not complete, but you get the idea. As an extra advantage, you can extend FunctionItem with extra properties like Name, Description, etc. per function.
As for a proper OO alternative, look into the Strategy design pattern (= subclassing).
And it's funny, because subclassing works the same... the vtable is actually a LUT, and FunctionItem becomes an abstract base class.

Compile-time method call validation for multiple parameters of the same type

Here is demonstration of the problem:
class Program
{
static double Func(double a, double b) { return a * 1000 + b * b; }
static void Main(string[] args)
{
var a = 1.1d;
var b = 2.2d;
Console.WriteLine(Func(a, b));
// this is the problem, function doesn't recognize when a and b
// "accidentally" exchanged, target is to make this row a compile-time error
Console.WriteLine(Func(b, a));
}
}
This become an issue if there are methods with many parameters (e.g. ten of double type):
double Func(double parameter1, double parameter2, ..., double parameter10);
Question: is there a way to validate parameters when calling method, so that programmer is less prone to do a mistake?
This is not an issue if parameter types are different. I thought what maybe wrapping into new types will help:
class A
{
private double _value;
public static implicit operator A(double value) { return new A() { _value = value }; }
public static implicit operator double(A value) { return value._value; }
}
class B
{
private double _value;
public static implicit operator B(double value) { return new B() { _value = value }; }
public static implicit operator double(B value) { return value._value; }
}
class Program
{
static double Func(A a, B b) { return a * 1000 + b * b; }
static void Main(string[] args)
{
A a = 1.1d;
B b = 2.2d;
Console.WriteLine(Func(a, b));
Console.WriteLine(Func(b, a)); // compile-time error! yay!
Console.WriteLine(Func(a, b) + 123.123d - a * 2); // implicit conversion power
Console.ReadKey();
}
}
And it does, but I am quite unsure if this method is efficient. I have doubts if this is a good idea at all. Is it? Or is there better one?
I know what I can be absolutely safe if I always call method like this (using named arguments method call)
Func(a:a, b:b);
This shouldn't bring any overhead in code, but a lot of typing. Wrapping is better because it is done once (creating new type is easy), but it probably has overhead.
If two arguments are of the same type, it's not possible to detect at compile-time, run-time or otherwise that the name of the argument variable corresponds to the name of the parameter. This is kind of an open question, but I will offer you a couple ideas.
As Mehrzad suggested, consider grouping parameters by some type. For example, instead of double Distance(double x1, double y1, double x2, double y2), consider double Distance(Point p1, Point p2)
In general, if your method has more than 4-5 parameters, consider refactoring. Maybe your method is trying to do too many things and the logic can be divided?
If what you actually want to do is to perform some check such as ensuring that a < b, consider looking into Code contracts. You could also use Debug.Assert(), but this only works at run-time.
I wouldn't recommend the kind of implicit conversion you propose. For me, it feels hacky and unintuitive that A a = 1.1 should have no semantic purpose other than compile-time checking parameters. Your ultimate goal is to make code more maintainable overall.
You should never have 10 parameters for a method.
Once you have around 4 parameters, begin to consider the use of a new class to contain those parameters... As an example, consider the preferences of a user navigating on a website...
void Main()
{
UserPreferences preference = new UserPreferences
{
BackgroundColor = "#fff",
ForegroundColor = "#000",
Language = "en-GB",
UtcOffSetTimeZone = 0
};
User aydin = new User(preference);
}
public class User
{
public User(UserPreferences preferences)
{
this.Preferences = preferences;
}
public UserPreferences Preferences { get; set; }
}
public class UserPreferences
{
public string BackgroundColor { get; set; }
public string ForegroundColor { get; set; }
public int UtcOffSetTimeZone { get; set; }
public string Language { get; set; }
}
Use an inherited class something like this
class Program
{
static double Func(List<Parent> l) { return l[0]._value * 1000 + l[1]._value * l[1]._value; }
static void Main(string[] args)
{
A a = 1.1d;
B b = 2.2d;
Console.WriteLine(Func(new List<Parent>() {a,b}));
Console.WriteLine(Func(new List<Parent>() { a, b })); // compile-time error! yay!
Console.WriteLine(Func(new List<Parent>() { a, b }) + 123.123d - a * 2); // implicit conversion power
Console.ReadKey();
}
}
class Parent
{
public double _value { get; set; }
}
class A : Parent
{
public static implicit operator A(double value) { return new A() { _value = value }; }
public static implicit operator double(A value) { return value._value; }
}
class B : Parent
{
public static implicit operator B(double value) { return new B() { _value = value }; }
public static implicit operator double(B value) { return value._value; }
}

Money Type enum

Class Coin has the following properties: MoneyType, Value, Diameter.
MoneyType is enum:
enum CoinType
{
Cent,
Nickel,
Dime,
QuarterDollar,
HalfDollar,
Dollar,
}
Each MoneyType should have specific Value and Diameter, for example Cent: Value = 1 and Diameter = 19, so if I assign MoneyType, Value and Diameter should be assigned automatically according to MoneyType. Not sure how to do this. Maybe some kind of enum tuples?
For example:
enum CoinType
{
(Cent, 1, 19),
(Nickel, 10, 21),
.....
}
I just want that every MoneyType has specific Value and Diameter.
Another way you can do it is by implementing your custom enum.
Source is modified according to your needs.
#region Base Abstract Class
public abstract class EnumBaseType<T> where T : EnumBaseType<T>
{
protected static List<T> enumValues = new List<T>();
public readonly string Key;
public readonly int Value;
public readonly int Diameter;
public EnumBaseType(string key, int value, int diameter)
{
Key = key;
Value = value;
Diameter = diameter;
enumValues.Add((T)this);
}
protected static System.Collections.ObjectModel.ReadOnlyCollection<T> GetBaseValues()
{
return enumValues.AsReadOnly();
}
protected static T GetBaseByKey(string key)
{
foreach (T t in enumValues)
{
if (t.Key == key) return t;
}
return null;
}
}
#endregion
#region Enhanced Enum Sample
public class MoneyType : EnumBaseType<MoneyType>
{
public static readonly MoneyType Cent = new MoneyType("Cent", 1, 19);
public static readonly MoneyType Nickel = new MoneyType("Nickel", 5, 25);
public static readonly MoneyType Dime = new MoneyType("Dime", 10, 30);
public static readonly MoneyType QuarterDollar = new MoneyType("QuarterDollar", 25, 15);
public static readonly MoneyType HalfDollar = new MoneyType("HalfDollar", 50, 100);
public static readonly MoneyType Dollar = new MoneyType("Dollar", 100, 29);
public MoneyType(string key, int value, int diameter)
: base(key, value, diameter)
{
}
public static ReadOnlyCollection<MoneyType> GetValues()
{
return GetBaseValues();
}
public static MoneyType GetByKey(string key)
{
return GetBaseByKey(key);
}
}
#endregion
public class Test
{
public Test()
{
foreach (MoneyType rating in MoneyType.GetValues())
{
Console.Out.WriteLine("Key:{0} Value:{1}", rating.Key, rating.Value);
if (rating == MoneyType.Dollar)
{
Console.Out.WriteLine("This is a dollar!");
}
}
foreach (MoneyType rating in MoneyType.GetValues())
{
if (rating.Diameter == MoneyType.Nickel.Diameter)
{
Console.Out.WriteLine("This is a Nickel diameter!");
}
}
}
}
source
EDIT:
Just found this: Type-safe-enum pattern
An enum is nothing more than an INT value with a name. It stores only one discrete value. What you want to use is a class.
UPDATE:
Sorry, about my mistake. It's actually been quite awhile since I've used C#. To make it up I've written out what I mean:
enum CoinType {
Cent=1,
Nickel=5,
Dime=10,
QuarterDollar=25,
HalfDollar=50,
Dollar=100,
}
class Coin {
public CoinType type;
public int Diameter {
get {
switch (type) {
case CoinType.Cent: return 19;
case CoinType.Nickel: return 25;
case CoinType.Dime: return 20;
case CoinType.QuarterDollar: return 40;
case CoinType.HalfDollar: return 40;
case CoinType.Dollar: return 40;
}
return 0;
}
}
}
You can add custom attributes onto the enum members.
enum CoinType
{
[Value=1]
[Diameter=19]
Cent,
...
}
You can then use reflection to get the info from the attributes.
You just need a mapping from CoinType to diameter and another from CoinType to value. Both can be done with a simple switch statement.
enum CoinType
{
Cent,
Nickel,
Dime,
QuarterDollar,
HalfDollar,
Dollar,
}
static class CoinTypeExts
{
static double Diameter(this CoinType coinType)
{
switch (coinType)
{
case Cent: return 19;
etc...
}
}
static double Value(this CoinType coinType)
{
switch (coinType)
{
case CoinType.Cent: return 1.0;
etc...
}
}
}

Delegates to generic operations where the generic type is unknown. How to create something like that?

Suppose I have the following code.
static class Store<T> {
public static T A;
public static T B;
public static T C;
}
public static class Store {
public static Value A = new Value(<T>(v) => Store<T>.A = v); //just an example of what I want
public static Value B = new Value(<T>(v) => Store<T>.B = v); //just an example of what I want
public static Value C = new Value(SetC<T>); //just an example of what I want
public static void SetA<T>(T value) { Store<T>.A = value; }
public static void SetB<T>(T value) { Store<T>.B = value; }
public static void SetC<T>(T value) { Store<T>.C = value; }
}
public class Value {
Action<T><T> _valueChanger; //just an example of what I want
public Value(Action<T><T> valueChanger) { //just an example of what I want
_valueChanger = valueChanger;
}
public void SetValue<T> (T value) {
_valueChanger<T>(value); //just an example of what I want
}
}
I want to write Store.A.SetValue(42) so that the value is saved to Store<int>.A. What can I write instead of the lines marked by "just an example of what I want" to make that happen? (I want to explore a solution that doesn't involve dictionaries or something similar)
Rephrasing the question:
I want to modify class Value (define some fields, write a constructor and write the method Value.SetValue(T value) ), then construct three different variables of type Value (A, B, C) in such a way that when I call Store.A.SetValue(42) the value Store<int>.A is changed to 42.
Another variation of the classes:
static class Holder<T> {
T Value { get; set; }
}
static class Store2<T> {
public static Holder<T> A = new Holder<T>();
public static Holder<T> B = new Holder<T>();
public static Holder<T> C = new Holder<T>();
}
public static class Store2 {
public static Value A = new Value2(Store2<>.A); //just an example of what I want
public static Value B = new Value2(Store2<>.B); //passing non-specific generic expression
public static Value C = new Value3({TFree}() => Store2<TFree>.C); //just an example of what I want
}
public class Value2 { //Non-generic class!
Holder{TFree}<TFree> _holder; //just an example of what I want
public Value(Holder{TFree}<TFree> holder) { //just an example of what I want
_holder = holder;
}
public void SetValue<T> (T value) {
_holder{T}.Value = value; //just an example of what I want
}
}
public class Value3 { //Non-generic class! (Another variation)
Func{TFree}<Holder<TFree>> _holderFactory; //just an example of what I want
public Value(Func{TFree}<Holder<TFree>> holderFactory) { //just an example of what I want
_holderFactory = holderFactory;
}
public void SetValue<T> (T value) {
Holder<T> holder = _holderFactory{T}(); //just an example of what I want
holder.Value = value;
}
}
Solution:
An easy reflection-free and collection-free solution was found using the answers to another question ( Emulating delegates with free generic type parameters in C# and Emulating delegates with free generic type parameters in C#). The solution is Delegates to generic operations where the generic type is unknown. How to create something like that?.
Use an array to store the values and access them through a property using an index
public static class Store<T>
{
public static readonly T[] Values = new T[3];
public static T A { get { return Values[0]; } set { Values[0] = value; } }
public static T B { get { return Values[1]; } set { Values[1] = value; } }
public static T C { get { return Values[2]; } set { Values[2] = value; } }
}
public static class Store
{
public static readonly Value A = new Value(0);
public static readonly Value B = new Value(1);
public static readonly Value C = new Value(2);
}
public class Value
{
private int _index;
public Value(int index)
{
_index = index;
}
public void SetValue<T>(T value)
{
Store<T>.Values[_index] = value;
}
public T GetValue<T>()
{
return Store<T>.Values[_index];
}
}
Since the constructor of Value is not aware of any generic type parameter, you cannot have any reference to a specific Store<T>.
UPDATE
Be aware of the fact that a copy of Store<T> will be created for every distinct type argument that you supplied for T. See this example
Store.A.SetValue(42);
Store.A.SetValue("Douglas Adams");
Store.A.SetValue(new DirectoryInfo(#"C:\"));
Store.A.SetValue(new List<int>());
var x1 = Store.A.GetValue<int>(); // --> 42
var x2 = Store.A.GetValue<string>(); // --> "Douglas Adams"
var x3 = Store.A.GetValue<DirectoryInfo>(); // --> DirectoryInfo{ C:\ }
var x4 = Store.A.GetValue<List<int>>(); // --> List<int>{ Count = 0 }
By using the debugger, you will see that four different values are stored in A at the same time! Of cause these are four differents A's that exist in four diffferent Store<T>.
The problem turned out to be solvable. Mike-z gave me a nearly right solution for the delegate-to-generic-method problem ( Emulating delegates with free generic type parameters in C#) which I modified to be a full solution: ( Emulating delegates with free generic type parameters in C#).
The solution this question becomes easy too. Interfaces can contain generic methods and we can use the interface-valued variables to store links to generic methods without specifying concrete type arguments. The following code utilizes the Store<T> class without modifications and uses the ISetter interface and ASetter/BSetter/CSetter "closures" to hold references to different generic members. The Value class stores the references in a ISetter-typed variable and uses the generic member which the _setter links to once the type argument T becomes available.
public interface ISetter {
void SetValue<T>(T value);
}
public static class Store {
public static Value A = new Value(new ASetter());
public static Value B = new Value(new BSetter());
public static Value C = new Value(new CSetter());
class ASetter : ISetter {
public void SetValue<T>(T value) { Store<T>.A = value; }
}
class BSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.B = value; }
}
class CSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.C = value; }
}
}
public class Value {
ISetter _setter;
public Value(ISetter setter) {
_setter = setter;
}
public void SetValue<T> (T value) {
_setter.SetValue<T>(value);
}
}

What's the equivalent of Java's enum in C#? [duplicate]

This question already has answers here:
C# vs Java Enum (for those new to C#)
(13 answers)
Closed 9 years ago.
What's the equivalent of Java's enum in C#?
Full Java enum functionality isn't available in C#. You can come reasonably close using nested types and a private constructor though. For example:
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<int, int, int> op;
internal GenericOperator(Func<int, int, int> op)
{
this.op = op;
}
public override int Execute(int left, int right)
{
return op(left, right);
}
}
}
Of course you don't have to use nested types, but they give the handy "custom behaviour" part which Java enums are nice for. In other cases you can just pass arguments to a private constructor to get a well-known restricted set of values.
A few things this doesn't give you:
Ordinal support
Switch support
EnumSet
Serialization/deserialization (as a singleton)
Some of that could probably be done with enough effort, though switch wouldn't really be feasible without hackery. Now if the language did something like this, it could do interesting things to make switch work by making the hackery automatic (e.g. declaring a load of const fields automatically, and changing any switch over the enum type to a switch over integers, only allowing "known" cases .)
Oh, and partial types mean you don't have to have all of the enum values in the same file. If each value got quite involved (which is definitely possible) each could have its own file.
Enums are one of the few language features that is better implemented in java than c#.
In java, enums are full fledged named instances of a type, while c# enums are basically named constants.
That being said, for the basic case, they will look similar. However in java, you have more power, in that you can add behavior to the individual enums, as they are full fledged classes.
is there some feature in particular you are looking for?
Here's another interesting idea. I came up with the following Enumeration base class:
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; }
}
}
It's got a type parameter basically just so the ordinal count will work properly across different derived enumerations. Jon's Operator example above then becomes:
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);
}
}
This gives a few advantages.
Ordinal support
Conversion to string and int which makes switch statements feasible
GetType() will give the same result for each of the values of a derived Enumeration type.
The Static methods from System.Enum can be added to the base Enumeration class to allow the same functionality.
You could probably use the old typesafe enum pattern that we used in Java before we got real ones (assuming that the ones in C# really aren't classes as a comment claims). The pattern is described just before the middle of this page
//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);
}
}
}
enum , or do you need something in particular that Java enums have but c# doesn't ?

Categories

Resources