【问题标题】:random enum value for a generic enum type extension method通用枚举类型扩展方法的随机枚举值
【发布时间】:2020-10-19 01:51:57
【问题描述】:

我想为 any Enum 编写一个扩展方法,该方法从该枚举中返回一个随机值,目前我得到了这个:

class Monster
{
    public enum presets
    {
     //some values
    }
    presets p = presets.randomEnum();
}
public static class Extensions
{
        public static T randomEnum<T>(this T en) where T : struct , IConvertible , IEnumerable<Enum>
        {
            if (!typeof(T).IsEnum) { throw new Exception("random enum variable is not an enum"); }
            Array values = en.ToArray();
            return (T)values.GetValue(Random.Next(values.Length));
        }
}

但是当我这样做时presets.randomEnum()Visual Studio 19 告诉我 Error CS0117 'Monster.presets' does not contain a definition for 'randomEnum'

注意:我不得不为那个 ext 方法做很多谷歌搜索,所以如果有一个我错过或只是没有想到的更简单的方法,我非常感谢它

【问题讨论】:

  • 你不能有一个静态的扩展方法......他们只是不存在。
  • 这能回答你的问题吗? Static extension methods
  • @Sweeper "你不能有静态扩展方法。" - 请解释一下?
  • @TheGeneral 当然方法声明标记为“静态”,以防您误解。 :-) 请参阅 Martheen 评论中链接的答案。我是这个意思。
  • @hiew1 一般的要点是,我创建了一个具有一些具有随机值的枚举属性的对象,并且作为该代的一部分,涉及其他枚举,我也想要随机值,所以我认为它是编写一个接受 any 枚举并从中返回随机值的函数是个好主意。老实说,我对此很陌生,它融化了我的大脑,所以如果我解释得很糟糕,我会道歉

标签: c# enums extension-methods


【解决方案1】:

扩展方法必须定义在类的顶部(即在命名空间内但不在另一个类中)。此外,你不能对它有那个 IEnumerable 约束,它太多了。这对我有用:

 public enum Presets
    {
        Test,
        Test2
    }


    public static class Extensions
    {
        public static T RandomEnum<T>(this T en) where T : struct, IConvertible
        {
            if (!typeof(T).IsEnum) { throw new Exception("random enum variable is not an enum"); }

            var random = new Random();
            var values = Enum.GetValues(typeof(T));
            return (T)values.GetValue(random.Next(values.Length));
        }
    }

【讨论】:

  • “Enum 和扩展方法都必须在类的顶部定义” - 不正确。 “(即在命名空间内但不在另一个类中)。” - 与句子的第一部分无关。
  • 您是否也尝试过使用 OP 的代码:presets p = presets.randomEnum();
  • Random 也最好定义为[System.ThreadStatic] private static Random __random = new Random();
【解决方案2】:

您的扩展方法看起来不错(我没有测试,我在手机上),但您的模板不太正确。你的约束太多了。

你基本上是这么说的..

  1. 通过输入where T : struct,您是说参数必须是不可为空的类型(枚举不可为空,这很好..)

  2. where T: IConvertible参数必须实现IConvertible接口(@98​​7654326@实现IConvertible。这里好)

  3. where T : IEnumerable&lt;enum&gt; 您的枚举似乎没有显式实现IEnumerable 接口,并且默认情况下也没有实现它 - 它不符合您对方法施加的参数要求。

编辑:我建议您删除 IEnumerable&lt;enum&gt; 约束,因为它是不必要的。

查看枚举: https://docs.microsoft.com/en-us/dotnet/api/system.enum?view=netcore-3.1

查看类型参数的约束:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2013-08-11
    • 1970-01-01
    相关资源
    最近更新 更多