Why can't we add static methods to enums? [duplicate] - c#

This question already has answers here:
Extension method on enumeration, not instance of enumeration
(7 answers)
Closed 8 years ago.
I wonder why we can't add static methods (only methods, not properties) into enums? Is there any explanation for that?
It would be very useful if it was allowed.
And I also want to learn who forbids us to do it? Is it IL or C#?
Edit:
I don't want to use extension methods. Because I dont need to pass an instance of that enum. I don't need it's value there...
I want to call something like FooTypes.GetGoodFoos() not something FooTypes.BadFoo.GetSomething()
Edit 2:
Is that only me who thinks this could be more useful rather than writing this method in another class?
public enum Colors
{
Red,
LightRed,
Pink,
/* .
.
. */
Green
public static Colors[] GetRedLikes()
{
return new Colors[]
{
Colors.Red,
Colors.LightRed,
Colors.Pink
}
}
}

As the other answers say, it's not possible.
I know, this does not answer your question, but I want to give an alternative to your example.
Because, basically what you try to archive is already possible with flags. So let me take your "GetRedLikes" example:
[Flags]
public enum Colors : byte
{
Transparent = 0, // = 0 (00000000)
Red = 1 << 0, // = 1 (00000001)
LightRed = 1 << 1, // = 2 (00000010)
Pink = 1 << 2, // = 4 (00000100)
Green = 1 << 3, // = 8 (00001000)
RedLikes = Colors.Red | Colors.LightRed | Colors.Pink // = 7 (00000111)
}
Then Colors.RedLikes will contain Red, LightRed and Pink. All the magic is done by bits, as always. Your condition then should look like this:
Colors c = Colors.LightRed;
if(c & Colors.RedLikes != 0)
{
// c is red-alike
}
Of course, this solution will not allow you to do very complex algorithms, it's no method type replacement. But it allows you to combine more than one enum in a set. If you need further functions, you have to build a method in an extra class.

I use static class for same cases:
public enum SomeEnum
{
Item1,
Item2,
Item3
}
public static class SomeEnumHelper
{
public static SomeEnum[] GetMainItems()
{
return new[] {SomeEnum.Item1, SomeEnum.Item2};
}
}

We can't add methods to enums because is how the language is made, and you are free to read the specification of the C# Language Specification
14.3 Enum members
The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No
two enum members can have the same name.
enum-member-declarations: enum-member-declaration
enum-member-declarations , enum-member-declaration
enum-member-declaration: attributesopt identifier attributesopt
identifier = constant-expression
Each enum member has an
associated constant value. The type of this value is the underlying
type for the containing enum. The constant value for each enum member
must be in the range of the underlying type for the enum.

Related

How would I convert a int to enum value at runtime when I have a string and an integer? [duplicate]

This question already has answers here:
Create instance of unknown Enum with string value using reflection in C#
(2 answers)
Closed 3 years ago.
What I have is a string variable that is the name of a enum. I have the integer of the enum. How would I convert that into instance of the enum itself?
Enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
string str = "TestEnum";
int intValue = 2;
I see many posts that require you to have an instance of the enum to get it's like this highly upvoted answer.
I need to do this at runtime.
Edit:
I am trying to write a class that gets and sets settings in an api that has hundreds of enums that represent settings.
The enums break are categorized by 5 basic setting types represented by five enums. These enums are like:
DoubleValueEnum
IntegerValueEnum
BooleanValueEnum
StringValueEnum
These enums are pointers to settings of type double, integer, string, bool. I believe that underneath the hood they have a database that keeps a table like this:
Type key value Represents
------- ------ ------- ---------------------------------
Double 23 2.745 DoubleValueEnum.DrawingWidth
Integer 5 18 IntegerValueEnum.PenColor
Double 54 15.9245 DoubleValueEnum.GridMajorSpacing
For doubles there is no "lower" enum that it is pointing to. For integer there is a deeper enum like "PenNumber.Red = 1, PenColor.Green = 2.
Hypothetical pen color:
Enum PenColor
{
Red = 1,
Blue = 2,
}
Each of these enums have hundreds of values. Each of these enums has a prewritten function the gets or sets the enum:
GetDoubleEnumValue(int, option)
GetIntegerValueEnum(int, option)
GetBooleanValueEnum(int, option)
GetStringValueEnum(int, option)
SetXXXXXEnumValue(enum, value)
SetDoubleEnumValue(int, int)
SetIntegerValueEnum(int, int)
SetBooleanValueEnum(int, int)
SetStringValueEnum(int, int)
Real example:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14);
For your given enum definition:
enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
enum TestEnum2
{
OnePoint1 = 1,
OnePoint2 = 2,
OnePoint3 = 3
}
Use Enum.Parse(Type, string) to parse the string value as an Enum value.
string str = "Two";
TestEnum valueAsEnum = (TestEnum)Enum.Parse(typeof(TestEnum), str);
However, you need to know they type of the Enum definition that you want to parse. If the exact type of the enum value is unknown, but you do know the potential types, then you can iterate through the types and test using the Enum.TryParse
string str = "Two";
object enumValue = null;
if (!Enum.TryParse(typeof(TestEnum), str, true, out enumValue))
Enum.TryParse(typeof(TestEnum2), str, true, out enumValue))
If you do not know the specific type of the enum but you do know the class name, you can use the Type.GetType Method to resolve the type
For this to work you do need to know the full namespace of type that you want to resolve, AND the assembly that the type is defined in must already be loaded.
The syntax to convert an int to an enum is discussed here: https://stackoverflow.com/a/56859286/1690217
In this example, we know that all of the enums reside in the API.Client.Enums namespace:
string str = "TestEnum";
int intValue = 2;
string ns = "API.Client.Enums";
Type enumType = Type.GetType($"{ns}.{str}");
// now we can parse the value:
object value = Enum.ToObject(enumType, (object)intValue);
Usually we do not need to bother with a lot of this conversion just to pass values between systems, the fact that the enum resolves to an integer means that for unknown types we should be able to write our logic to just deal with the integer, and only convert it back to a specific enum when you need it.
It looks like you are trying to use BitWise operations on Enum values to allow a single setting property to represent multiple optional states.
For this sir Enums have support built in if you use the Flags attribute:
There is a good SO dicussion that covers this too: What does the [Flags] Enum Attribute mean in C#?
Lets look at PenColor enum first:
[Flag]
enum PenColor : int
{
None = 0 // 0
Red = 1 << 0, // 1
Green = 1 << 1, // 2
Blue = 1 << 2 // 4
}
By defining the discrete enums with base-2 values, we can now use either bitwise operations on the PenColor enum, or we can use simple integer addition/subtraction:
PenColor cyan = PenColor.Green | PenColor.Blue;
int cyanInt = (int)PenColor.Green + (int)PenColor.Blue;
PenColor cyanCasted = (PenColor)cyanInt;
All of those statements will be equivalent. So potentially this syntax replaces your SetIntegerValueEnum, but it relies on the enum definition being implemented with base-2 values.
To test, this statement should be true:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14)
== (int)IntegerValueEnum.swDxfVersion + (int)swDxfFormat_e.swDxfFormat_R14)
== IntegerValueEnum.swDxfVersion | swDxfFormat_e.swDxfFormat_R14
The last option will only work if the [Flags] attribute decorates the enum type definition.
You can then use this in switching logic or comparisons
PenColor cyan = PenColor.Green | PenColor.Blue;
bool hasBlue = cyan & PenColor.Blue == PenColor.Blue;
// you can also use the slower Enum.HasFlag
hasBlue = cyan.HasFlag(PenColor.Blue);

Can you have multiple enum values for the same integer? [duplicate]

This question already has answers here:
Non-unique enum values
(8 answers)
Closed 9 years ago.
In .NET can you have multiple enum values for the same integer?
eg.
public enum PersonGender
{
Unknown = 0,
Male = 1,
Female = 2,
Intersex = 3,
Indeterminate = 3,
NonStated = 9,
InadequatelyDescribed = 9
}
In C#, this is allowed, as per the C# Language Specication, version 4. Section 1.10 Enums doesn't explicitly mention the possibility but, later on in section 14 Enums, 14.3, we see:
Multiple enum members may share the same associated value. The example
enum Color {
Red,
Green,
Blue,
Max = Blue
}
shows an enum in which two enum members - Blue and Max - have the same associated value.
That works fine. There is absolutely nothing wrong with the code you posted. It compiles just fine and works in code, with the caveat that
PersonGender.NonStated == PersonGender.InadequatelyDescribed
I found this StackOverflow post related to this question. I think there is a very sensible discussion of how this works. Non-unique enum values
Now, I might also add that it is my opinion this would be an ambiguous (and therefore improper) use of an enum. It's important to write code that makes sense to someone else reading it, and in this case, I would be put off by this enum.
I would suggest that an enum would not be a right thing to use in your context instead you can use create a class and methods which can resolve your purpose. Something like this in your class:-
class A
{
static readonly ABCD= new Dictionary<int,string>
{
{ 1, "X" },
{ 2, "X" },
{ 3, "Y" }
{ 4, "Y" }
}
}

How to have a set of enumeration values in C#?

Assume i have an enumeration:
namespace System.Windows.Forms
{
public enum DialogResult { None, OK, Cancel, Abort, Retry, Ignore, Yes, No }
}
i want to declare a "set" made up of these enumerated types
ShowForm(Form frm, DialogResults allowedResults)
In other languages you would declare:
public DialogResults = set of DialogResult;
And then i can use
ShowForm(frm, DialogResult.OK | DialogResult.Retry);
C# has the notion of Flags, pseudocode:
[Flags]
public enum DialogResults { DialogResult.None, DialogResult.OK, DialogResult.Cancel, DialogResult.Abort, DialogResult.Retry, DialogResult.Ignore, DialogResult.Yes, DialogResult.No }
problem with that it's not real code - Flags does not instruct the compiler to create a set of flags.
in one case the type should only allow one value (DialogResult)
in another case the type should allow multiple values of above (DialogResults)
How can i have a "set" of enumerated types?
Note: i assume it's not possible in C#. If that's the answer: it's okay to say so - the question is answered.
Note: Just because i believe C# language doesn't have the feature doesn't mean it doesn't have the feature - i may just not have found it yet.
Update: another example:
Assume i have an enumeration:
public enum PatronTier
{
Gold = 1,
Platinum = 2,
Diamond = 3,
SevenStar = 7 //Yes, seven
}
i want to declare a "set" made up of these enumerated types
public Tournament
{
public PatronTiers EligibleTiers { get; set; }
}
In other languages you would declare:
public PatronTiers = set of PatronTier;
And then i can use:
tournament.EligibleTiers = PatronTier.Gold | PatronTier.SevenStar;
C# has the notion of Flags, pseudocode:
[Flags]
public enum PatronTiers { PatronTier.Gold, PatronTier.Platinum, PatronTier.Diamond, PatronTier.SevenStar }
problem with that it's not real code.
How can i have a "set" of enumerated types?
Seems like you want an array of things. There are array types in C#, but nothing that is directly equivalent to your examples in terms of compiler support, closest is perhaps DialogResults[], an array of DialogResults.
Try supplying a HashSet of the items you allow. HashSet<T> implements ISet<T>, and it's usually best to work against interfaces than concrete types, especially for method signatures:
ShowForm(Form frm, ISet<DialogResults> allowedResults);
Then you can use Contains to test for items:
if (allowedResults.Contains(DialogResults.OK))
{
}
Somewhat pointless alternative: you could always implement your own Set<Enum> type using Jon Skeet's Unconstrained Melody to give you a nicer syntax from the perspective of the caller and get a little closer to your examples.
I don't suppose you just mean using something like this?
var DialogResults = Enum.GetValues(typeof(DialogResult));
with a .Select(dr => (DialogResult)dr).ToArray() if you want it strongly typed.
I think you want something like this:
foreach (var item in System.Enum.GetValues(typeof(PatronTier)))
{
Console.WriteLine(item);
}

What is main use of Enumeration?

What is main use of Enumeration in c#?
Edited:-
suppose I want to compare the string variable with the any enumeration item then how i can do this in c# ?
The definition in MSDN is a good place to start.
An enumeration type (also named an
enumeration or an enum) provides an
efficient way to define a set of named
integral constants that may be
assigned to a variable.
The main benefit of this is that constants can be referred to in a consistent, expressive and type safe way.
Take for example this very simple Employee class with a constructor:
You could do it like this:
public class Employee
{
private string _sex;
public Employee(string sex)
{
_sex = sex;
}
}
But now you are relying upon users to enter just the right value for that string.
Using enums, you can instead have:
public enum Sex
{
Male = 10,
Female = 20
}
public class Employee
{
private Sex _sex;
public Employee(Sex sex)
{
_sex = sex;
}
}
This suddenly allows consumers of the Employee class to use it much more easily:
Employee employee = new Employee("Male");
Becomes:
Employee employee = new Employee(Sex.Male);
Often you find you have something - data, a classification, whatever - which is best expressed as one of several discrete states which can be represented with integers. The classic example is months of the year. We would like the months of the year to be representable as both strings ("August 19, 2010") and as numbers ("8/19/2010"). Enum provides a concise way to assign names to a bunch of integers, so we can use simple loops through integers to move through months.
Enums are strongly typed constants. Enumerations are special sets of named values which all maps to a set of numbers, usually integers. They come in handy when you wish to be able to choose between a set of constant values, and with each possible value relating to a number, they can be used in a wide range of situations. As you will see in our example, enumerations are defined above classes, inside our namespace. This means we can use enumerations from all classes within the same namespace.
using System;
namespace ConsoleApplication1
{
public enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
class Program
{
static void Main(string[] args)
{
Days day = Days.Monday;
Console.WriteLine((int)day);
Console.ReadLine();
}
}
}
Enumeration (Enum) is a variable type. We can find this variable type in C, C# and many other languages.
Basic Idea for Enum is that if we have a group of variable of integer type (by default) then instead of using too much int values just use a Enum. It is efficient way. Let suppose you want to write rainbow colours then you may write like this:
const int Red = 1;
const int Orange = 2;
const int Yellow = 3;
const int Green = 4;
const int Blue = 5;
const int Indigo = 6;
const int Violet = 7;
here you can see that too many int declarations. If you or your program by mistake change the value of any integer varialbe i.e. Violet = 115 instead of 7 then it will very hard to debug.
So, here comes Enum. You can define Enum for any group of variables type integers. For Enum you may write your code like this:
enum rainBowColors
{
red=1,
orange=2,
yellow=3,
green,
blue=8,
indigo=8,
violet=16)
};
rainBowColors is a type and only other variables of the same type can be assigned to this. In C#/C++ you need to type casting while in C you do not to type cast.
Now, if you want to declare a variable of type rainBowColors then in C
enum rainBowColors variableOne = red;
And in C# / C++ you can do this as:
rainBowColors variableOne = red;
There are two meanings of enumeration in C#.
An enumeration (noun) is a set of named values. Example:
public enum Result {
True,
False,
FileNotFound
}
Enumeration (noun form of the verb enumerate) is when you step through the items in a collection.
The IEnumerable<T> interface is used by classes that provide the ability to be enumerated. An array is a simple example of such a class. Another example is how LINQ uses it to return results as enumerable collections.
Edit:
If you want to compare a string to an enum value, you either have to parse the string to the enum type:
if ((Result)Enum.Parse(typeof(Result), theString) == Result.True) ...
or convert the enum value to a string:
if (theString == Result.True.ToString()) ...
(Be careful how you compare the values, depending on whether you want a case sensetive match or not.)
If you want to enumerate a collection and look for a string, you can use the foreach command:
foreach (string s in theCollection) {
if (s == theString) {
// found
}
}
Another advantage of using Enum is that in case of any of the integer value needs to be changed, we need to change only Enum definition and we can avoid changing code all over the place.
An enumeration type (also named an enumeration or an enum) provides an efficient way to define a set of named integral constants that may be assigned to a variable.
http://msdn.microsoft.com/en-us/library/cc138362.aspx
Enumeration (ENUM)
An enum is a value type with a set of related named constants often referred to as an enumerator list. The enum keyword is used to declare an enumeration. It is a primitive data type, which is user defined.
Enums type can be integer (float, int, byte, double etc.). But if you used beside int it has to be cast.
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
Lets Take an Example we are taking normal constant in a class like
int a=10;
by mistakely we assign new value to that variable in that same class like
a=20;
then we will get wrong data when we want access them.
enum provide secure way of accessing constant.
Also if we have many feild constant in a class we had to memorize them if we want to use them in a class.
but enum contains group of related name constant, if we want to access the constant then only we had to memorize enum name.
Enumerations in my experience have worked in very specific cases and should be used when you absolutely need to maintain this in your application. Problems come into play with Enums when you are working with multiple developers and some new developer comes on to a project and can adds a enum to the application no errors everything builds but then you have another full stack developer that maintains this same list in a lookup table in a different order. Kaboom!!!!
Burned way to many times with that one even if not intentional. Rule of thumb don't maintain a list of enums in a app over 5 or 6 items. If higher you might as well store them in a lookup table in the DB of your choice.

Extending an enum via inheritance

I know this rather goes against the idea of enums, but is it possible to extend enums in C#/Java? I mean "extend" in both the sense of adding new values to an enum, but also in the OO sense of inheriting from an existing enum.
I assume it's not possible in Java, as it only got them fairly recently (Java 5?). C# seems more forgiving of people that want to do crazy things, though, so I thought it might be possible some way. Presumably it could be hacked up via reflection (not that you'd every actually use that method)?
I'm not necessarily interested in implementing any given method, it just provoked my curiosity when it occurred to me :-)
The reason you can't extend Enums is because it would lead to problems with polymorphism.
Say you have an enum MyEnum with values A, B, and C , and extend it with value D as MyExtEnum.
Suppose a method expects a myEnum value somewhere, for instance as a parameter. It should be legal to supply a MyExtEnum value, because it's a subtype, but now what are you going to do when it turns out the value is D?
To eliminate this problem, extending enums is illegal
You're going the wrong way: a subclass of an enum would have fewer entries.
In pseudocode, think:
enum Animal { Mosquito, Dog, Cat };
enum Mammal : Animal { Dog, Cat }; // (not valid C#)
Any method that can accept an Animal should be able to accept a Mammal, but not the other way around. Subclassing is for making something more specific, not more general. That's why "object" is the root of the class hierarchy. Likewise, if enums were inheritable, then a hypothetical root of the enum hierarchy would have every possible symbol.
But no, C#/Java don't allow sub-enums, AFAICT, though it would be really useful at times. It's probably because they chose to implement Enums as ints (like C) instead of interned symbols (like Lisp). (Above, what does (Animal)1 represent, and what does (Mammal)1 represent, and are they the same value?)
You could write your own enum-like class (with a different name) that provided this, though. With C# attributes it might even look kind of nice.
When built-in enums aren't enough, you can do it the old fashion way and craft your own. For example, if you wanted to add an additional property, for example, a description field, you could do it as follows:
public class Action {
public string Name {get; private set;}
public string Description {get; private set;}
private Action(string name, string description) {
Name = name;
Description = description;
}
public static Action DoIt = new Action("Do it", "This does things");
public static Action StopIt = new Action("Stop It", "This stops things");
}
You can then treat it like an enum like so:
public void ProcessAction(Action a) {
Console.WriteLine("Performing action: " + a.Name)
if (a == Action.DoIt) {
// ... and so on
}
}
The trick is to make sure that the constructor is private (or protected if you want to inherit), and that your instances are static.
Enums are supposed to represent the enumeration of all possible values, so extending rather does go against the idea.
However, what you can do in Java (and presumably C++0x) is have an interface instead of a enum class. Then put you standard values in an enum that implements the feature. Obviously you don't get to use java.util.EnumSet and the like. This is the approach taken in "more NIO features", which should be in JDK7.
public interface Result {
String name();
String toString();
}
public enum StandardResults implements Result {
TRUE, FALSE
}
public enum WTFResults implements Result {
FILE_NOT_FOUND
}
You can use .NET reflection to retrieve the labels and values from an existing enum at run-time (Enum.GetNames() and Enum.GetValues() are the two specific methods you would use) and then use code injection to create a new one with those elements plus some new ones. This seems somewhat analagous to "inheriting from an existing enum".
I didn't see anyone else mention this but the ordinal value of an enum is important. For example, with grails when you save an enum to the database it uses the ordinal value. If you could somehow extend an enum, what would be the ordinal values of your extensions? If you extended it in multiple places how could you preserve some kind of order to these ordinals? Chaos/instability in the ordinal values would be a bad thing which is probably another reason why the language designers have not touched this.
Another difficulty if you were the language designer, how can you preserve the functionality of the values() method which is supposed to return all of the enum values. What would you invoke this on and how would it gather up all of the values?
Adding enums is a fairly common thing to do if you go back to the source code and edit, any other way (inheritance or reflection, if either is possible) is likely to come back and hit you when you get an upgrade of the library and they have introduced the same enum name or the same enum value - I have seen plenty of lowlevel code where the integer number matches to the binary encoding, where you would run into problems
Ideally code referencing enums should be written as equals only (or switches), and try to be future proof by not expecting the enum set to be const
If you mean extends in the Base class sense, then in Java... no.
But you can extend an enum value to have properties and methods if that's what you mean.
For example, the following uses a Bracket enum:
class Person {
enum Bracket {
Low(0, 12000),
Middle(12000, 60000),
Upper(60000, 100000);
private final int low;
private final int high;
Brackets(int low, int high) {
this.low = low;
this.high = high;
}
public int getLow() {
return low;
}
public int getHigh() {
return high;
}
public boolean isWithin(int value) {
return value >= low && value <= high;
}
public String toString() {
return "Bracket " + low + " to " + high;
}
}
private Bracket bracket;
private String name;
public Person(String name, Bracket bracket) {
this.bracket = bracket;
this.name = name;
}
public String toString() {
return name + " in " + bracket;
}
}
Saw a post regarding this for Java a while back, check out http://www.javaspecialists.eu/archive/Issue161.html .
I would like to be able to add values to C# enumerations which are combinations of existing values. For example (this is what I want to do):
AnchorStyles is defined as
public enum AnchorStyles {
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8,
}
and I would like to add an AnchorStyles.BottomRight = Right + Bottom so instead of saying
my_ctrl.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
I can just say
my_ctrl.Anchor = AnchorStyles.BottomRight;
This doesn't cause any of the problems that have been mentioned above, so it would be nice if it was possible.
A temporary/local workaround, when you just want very local/one time usage:
enum Animals { Dog, Cat }
enum AnimalsExt { Dog = Animals.Dog, Cat= Animals.Cat, MyOther}
// BUT CAST THEM when using:
var xyz = AnimalsExt.Cat;
MethodThatNeedsAnimal( (Animals)xyz );
See all answers at: Enum "Inheritance"
You can't inherit from/extend an enum, you can use attributes to declare a description. If you're looking for an integer value, that's built-in.
Hmmm - as far as I know, this can't be done - enumerations are written at design-time and are used as a convenience to the programmer.
I'm pretty sure that when the code is compiled, the equivalent values will be substituted for the names in your enumeration, thereby removing the concept of an enumeration and (therefore) the ability to extend it.
Some time back even i wanted to do something like this and found that enum extensions would voilate lot of basic concepts... (Not just polymorphisim)
But still u might need to do if the enum is declared in external library and
Remember you should make a special caution when using this enum extensions...
public enum MyEnum { A = 1, B = 2, C = 4 }
public const MyEnum D = (MyEnum)(8);
public const MyEnum E = (MyEnum)(16);
func1{
MyEnum EnumValue = D;
switch (EnumValue){
case D: break;
case E: break;
case MyEnum.A: break;
case MyEnum.B: break;
}
}
As far as java is concerned it is not allowed because adding elements to an enum would effectively create a super class rather than a sub class.
Consider:
enum Person (JOHN SAM}
enum Student extends Person {HARVEY ROSS}
A general use case of Polymorphism would be
Person person = Student.ROSS; //not legal
which is clearly wrong.

Categories