开发者

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开发者_如何学C:
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.


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.


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.


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


I would just use something like IEnumerable<KeyValuePair<string,short>> or Dictionary<string,short>... you can add your extensions to IDictionary or IEnumerable if you want.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜