【问题标题】:Help in creating Enum extension helper帮助创建枚举扩展助手
【发布时间】:2013-11-04 00:50:35
【问题描述】:

以这个枚举为例:

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

我希望有这样的扩展方法:

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

知道如何实现吗?

它需要对 int、short 等通用,并且对通用枚​​举也是通用的,不限于 PersonName。

【问题讨论】:

  • 这是不可能的。 (您不能包含基于enum 的基础类型的方法)
  • 为什么需要扩展方法来执行此操作?转换到底层类型已经像(int) SomeEnum.SomeValue 一样简单

标签: c# .net


【解决方案1】:

这是完全不可能的。

您不能基于enum 的基础类型来限制方法。

说明:

您可以尝试这样做:

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

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

【讨论】:

【解决方案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,标准类型),然后是第一种。

【讨论】:

    【解决方案3】:

    你有什么理由不能把它变成一门课吗?在类的上下文中它可能更有意义。

    【讨论】:

    • 好点。以及如何使用通货再膨胀获得个人财产名称?还是每个人都应该返回字典?我会考虑一下。但是这个问题对我来说仍然很有趣。
    【解决方案4】:

    我只会使用IEnumerable&lt;KeyValuePair&lt;string,short&gt;&gt;Dictionary&lt;string,short&gt; 之类的东西...如果需要,您可以将扩展添加到 IDictionary 或 IEnumerable。

    【讨论】:

    • 这就是我现在要使用的。但是关于这个问题,我想要很多时间,但据我所知这是不可能实现的。
    【解决方案5】:

    我相信您应该能够在 PersonName 类上定义扩展方法:

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

    侧节点:不知何故,我希望您问题中的代码过于简化,因为将个人存储库实现为枚举似乎不太正确:)

    【讨论】:

    • 我希望它是通用的。当然这是一个例子:)
    • 抱歉,您的问题中没有提到这一点。恐怕我不确定您在这种情况下所说的“通用”是什么意思,但似乎其他人已经弄清楚了:)
    猜你喜欢
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多