简体   繁体   中英

Help in creating Enum extension helper

Take this enum for example:

public enum PersonName : short
{
    Mike = 1,
    Robert= 2
}

I wnat to have en extension method like this:

 PersonName person = PersonName.Robert; short personId = person.GetId(); //Instead of: short personId = (short)person; 

Any idea how to implement this?

it need to be generic to int, short etc..., and to generic enums as well, not limited to PersonName.

Well, its sort of possible, but on the flip side you will have to specify what the underlying type is:

public static T GetId<T>(this Enum value) 
                        where T : struct, IComparable, IFormattable, IConvertible
{
    return (T)Convert.ChangeType(value, typeof(T));
}

since System.Enum is the base class of all enum types. Call it:

PersonName person = PersonName.Robert;
short personId = person.GetId<short>();

Since you can cast almost anything to long , you could even have this:

public static long GetId(this Enum value)
{
    return Convert.ToInt64(value);
}

and call:

PersonName person = PersonName.Robert;
long personId = person.GetId();

What is otherwise possible is to get an object instance returned, like this or so:

public static object GetId(this Enum value)
{
    return Convert.ChangeType(task, Enum.GetUnderlyingType(value.GetType()));
}

PersonName person = PersonName.Robert;
var personId = (short)person.GetId(); 
// but that sort of defeats the purpose isnt it?

All of which involves some sort of boxing and unboxing. The second approach looks better (you could even make it int , the standard type) and then the first.

This is completely impossible.

You cannot constrain a method based on an enum 's underlying type.

Explanation:

Here is how you might try to do this:

public static TNumber GetId<TEnum, TNumber>(this TEnum val) 
       where TEnum : Enum 
       where TEnum based on TNumber

The first constraint is unfortunately not allowed by C# , and the second constraint is not supported by the CLR.

I believe you should be able to define an extension method on the PersonName class:

public static class PersonExtensions // now that sounds weird...
{
    public static short GetID (this PersonName name)
    {
        return (short) name;
    }
}

Side node: I somehow hope that the code in your question is overly simplified, as it does not seem quite right to implement a person repository as an enum :)

Is there any reason you can't turn it into a class? It would probably make more sense in context of a class.

我只想使用像IEnumerable<KeyValuePair<string,short>>Dictionary<string,short> ...你可以根据需要将你的扩展添加到IDictionary或IEnumerable。

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