16

Given a constructor

public MyObject(int id){
 ID = id;
}

And two enums:

public enum MyEnum1{
 Something = 1,
 Anotherthing = 2
}
public enum MyEnum2{
 Dodo = 1,
 Moustache= 2
}

Is it possible to pass in a generic enum as a parameter of the constructor? I'm looking for a solution along the lines of:

public MyObject(enum someEnum){
 ID = (int)someEnum;
}

So you can do:

var newObject = new MyObject(MyEnum1.Something);
var anotherObject = new MyObject(MyEnum2.Dodo);
Martin Verjans
4,8361 gold badge26 silver badges49 bronze badges
asked Sep 8, 2016 at 13:26
6
  • 5
    You can receive the parameter as Integer, and convert your enums to Integers when you pass them. Commented Sep 8, 2016 at 13:28
  • You can't do a generic constructor in C#. The best you could do is to write a nongeneric base class with a generic subclass, then make the enum type a type parameter for the generic subclass. Awkward. MyBase b = new MySub<EnumA>(EnumA.SomeValue); int n = b.ID; Commented Sep 8, 2016 at 13:29
  • MyObject(MyEnum1 enum1Selection){} but integer is better Commented Sep 8, 2016 at 13:29
  • new MyObject((int)MyEnum1.Something); ? Commented Sep 8, 2016 at 13:31
  • upvote @SuperPeanut, but, I would create a "objectType" enum and pass that to a factory that in turn creates the right thing with the right enum parameter. var newObject = myFactory.Create(ObjectType.One). Commented Sep 8, 2016 at 13:45

6 Answers 6

10

Another option would be:

public MyObject(Enum someEnum){
 ID = Convert.ToInt32(someEnum);
}

This way you can use it like you requested without having to cast to int each time you call your contstructors:

var newObject = new MyObject(MyEnum1.Something);
var anotherObject = new MyObject(MyEnum2.Dodo);
answered Sep 8, 2016 at 13:37
Sign up to request clarification or add additional context in comments.

1 Comment

I'm trying to do this in a ctor of a class and there it seems it won't allow that. Are methods and ctors different in that point? Edit: it seems Attributes are special there and it's not allowed there.
7

Why do you want to pass the enums, while you could pass integers ?

var newObject = new MyObject((int)MyEnum1.Something);
var anotherObject = new MyObject((int)MyEnum2.Dodo);

and use your first constructor :

public MyObject(int id){
 ID = id;
}
answered Sep 8, 2016 at 13:30

3 Comments

Yup this is what I was doing already, would just look more readable if I could pass the enum in directly
If it is about readability, you can use @HimBromBeere solution with a generic constructor, you have to write the enum name twice but it looks all right... All depends on what you want
Because Enum can have attribute Flags
6

Just use a generic constructor:

class MyObject<T> {
 public MyObject(T someEnum) where T : struct, IConvertible
 {
 if (!typeof(T).IsEnum) 
 throw new ArgumentException("Not an enum");
 ID = Convert.ToInt32(someEnum);
 }
}

Now you can easily call it like this:

var m = new MyObject<MyEnum>(MyEnum1.Something);

But easier would be to pass the enum as integer to the constructor as mentioned in other answers.

EDIT: As of C# 7.3 you can use an enum-constraint right away:

class MyObject<T> where T: Enum { ... }
answered Sep 8, 2016 at 13:42

3 Comments

You know you can't use Enum as a constraint? Life would be easier if you could but it won't compile.
@Ben You´re right, I updated the answer appropriately. Unfortunately you´re loosing compiler-type check against Enum with this approach making it possible to pass instances of int to the method as well.
I am painfully aware of this. My day has been spent trying to find as robust of a solution as possible. But sadly the above is about as good as you'll get!
0

I have tried to do this with Attributes and it seems Enum as parameter in Attributes are not allowed. Therefore I had to do this workaround:

public MyCustomAttribute(object myEnumParameter)
{
 if (myEnumParameteris not Enum)
 {
 throw new ArgumentException("myEnumParameter is not an enum", 
 nameof(myEnumParameter));
 }
 MyEnumProperty = (Enum)myEnumParameter;
}
answered Jun 11, 2024 at 9:42

Comments

-1

Well, if you really need to make this call generic for a wide variety of types, then IMHO you should use:

  1. Type.IsEnum to check if your argument is really an Enum;
  2. Enum.GetUnderlyingType to know what type is your argument is based on (it's not necessarily an Int32);
  3. Now cast your object.

    public static Int32 GetAnInt<T>(T arg) where T : struct
    {
     if ((typeof(T).IsEnum))
     {
     var underlyingType = typeof(T).GetEnumUnderlyingType();
     if (underlyingType == typeof(Int32)
     || underlyingType == typeof(Int16)) //etc.
     {
     try
     {
     dynamic value = arg;
     var result = (Int32)value; // can throw InvalidCast!
     return result;
     }
     catch
     {
     throw;
     }
     }
     else
     {
     throw new InvalidCastException("Underlying type
     is certainly not castable to Int32!");
     }
     }
     else
     {
     throw new InvalidCastException("Not an Enum!");
     }
    }
    

    That way you achieve the beautiful syntax of: var j = GetAnInt(MyEnum.FirstValue);

answered Sep 8, 2016 at 13:50

2 Comments

And I'm almost certain you may add a lot of different checks and polish this code for years =)
And yes, it's easier to pass an integer.
-2

Are you using properties enum or parameters.

public enum Enum1{}
public Enum1 enum1 { get;set; }
public MyObject()
{
 ID = (int)enum1;
}

Just try it. I hope it is useful.

CDspace
2,69919 gold badges32 silver badges39 bronze badges
answered Sep 8, 2016 at 13:49

2 Comments

How exactly does it answer his question?
And what will you get accessing a member property from a constructor?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.