2010-02-18 136 views
3

拿这个枚举例如:帮助创建枚举扩展帮助

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

我wnat有恩这样的扩展方法:

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

任何想法如何实现这一点?

它需要是通用的int,short等...以及通用枚举,以及不限于PersonName。

+0

你在问什么? – SLaks 2010-02-18 22:45:30

+0

这是不可能的。 (你不能建立一个基于'enum'的基础类型的方法) – SLaks 2010-02-18 22:53:44

+0

为什么你需要一个扩展方法来做到这一点?投射到基础类型已经很简单,如'(int)SomeEnum.SomeValue' – 2010-02-19 08:07:10

回答

2

这是完全不可能的。

您不能约束基于enum的基础类型的方法。

说明:

这里是如何你可以试试这样做:

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

第一个条件是unfortunately not allowed by C#,第二约束不是由CLR支持。

+0

你可以“排序”(当然,你创建效果) - http://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx – adrianbanks 2010-02-18 23:07:23

+0

另见:http://stackoverflow.com/questions/7244/anyone-know-a-good-workaround-for-the-lack-of-an-enum-generic-constraint – 2010-02-19 08:08:29

0

我相信你应该能够在PersonName类中定义的扩展方法:

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

端节点:不知何故,我希望在你的问题的代码是过于简化的,因为它似乎并不十分权利实施一个人存储库作为枚举:)

+0

我希望它是一个通用的。当然这是一个例子:) – 2010-02-18 22:53:33

+0

对不起,没有在你的问题中发现。恐怕我不确定在这种情况下你的意思是“通用”,但似乎其他人已经想通了:) – 2010-02-18 23:13:46

0

是否有任何理由,你不能把它变成一个类?在一个班级的背景下,这可能会更有意义。

+0

好点。以及如何使用reflation获取人物属性名称?或者每个人都应该返回字典?我会考虑一下。这个问题对我来说仍然很有趣。 – 2010-02-18 22:52:39

0

我只想使用类似IEnumerable<KeyValuePair<string,short>>Dictionary<string,short> ......如果需要,您可以将扩展添加到IDictionary或IEnumerable。

+0

那我现在要用的。但是关于这个问题,我想要很多时间,但从我的知识来看,这是不可能实现的。 – 2010-02-18 22:55:50

2

那么,它的排序的可能,但在另一面,你将有指定的基本类型是什么:

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

因为System.Enum是基类所有枚举类型。说它:

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

既然你可以投几乎什么long,你甚至可以有这样的:

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

,并呼吁:

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

是什么,否则可能是得到一个object实例返回,像这样左右:

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? 

所有这些都涉及某种拳击和拆箱。第二种方法看起来更好(甚至可以使它成为标准类型int),然后是第一种。