简体   繁体   中英

random enum value for a generic enum type extension method

Id like to write an extension method for any Enum that returns a random value from that enum, currently ive got this:

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));
        }
}

but when i do presets.randomEnum() Visual Studio 19 tells me that Error CS0117 'Monster.presets' does not contain a definition for 'randomEnum'

NOTE: i had to do ALOT of googling for that ext method so if theres an easier way that i missed or just didn't think of, id greatly appreciate it

The extension method must be defined at the top of the class (ie inside of a namespace but not in another class). Also, you can't have that IEnumerable constraint on it, it is too much. This works for me:

 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));
        }
    }

Your extension method looks fine (I did not test, I am on my mobile), but your templating is not quite right. You have too many constraints.

You are basically saying that..

  1. By putting where T : struct you are saying the argument must be a non-nullable type (enum's are not nullable, good here..)

  2. where T: IConvertible The argument must implement the IConvertible interface ( enum implements IConvertible . Good here)

  3. where T : IEnumerable<enum> It does not appear that your enum is explicitly implementing the IEnumerable interface, and it doesn't implement it by default - it doesn't meet the parameter requirements that you have imposed upon your method.

Edit : I recommend that you remove the IEnumerable<enum> constraints as it is unnecessary.

See enum: https://docs.microsoft.com/en-us/dotnet/api/system.enum?view=netcore-3.1

See Constraints on Type Parameters: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

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