简体   繁体   中英

Generic enum as method parameter

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

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

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

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM