4

I have an enum that looks like the following:

public enum EnumWeapons
{
    Fists = new WeaponFists(),
    Sword = new WeaponSword(),
    Bow = new WeaponBow(),
    Staff = new WeaponStaff()
}

Which are derived from the base class Weapon.

Is it possible to use an enum in this way?

If so, will I be able to do something like the following? :

public Weapon weapon = (Weapon)EnumWeapons.Fists;

My attempts haven't worked as intended, and any help or guidance is appreciated :). Thank you!

4
  • I would say enums are a typed textual representation of an integer. and you can't use class types (and inheritance) on them Commented Dec 28, 2011 at 14:22
  • Why not give it a try yourself? Commented Dec 28, 2011 at 14:23
  • This is not the way enums work. What exactly are you trying to do? It looks like you want the factory pattern. Commented Dec 28, 2011 at 14:24
  • Well, I'm trying to have a list of weapons which can be assigned to a player(I'm looking into game development a bit and am very new at it). Commented Dec 28, 2011 at 14:27

9 Answers 9

11

This is not possible, the underlying type of an enum are various integral types. From the documentation:

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

Also, I don't even think what you are trying to do makes sense. When you want a weapon, do you really want the same instance every time? I doubt it.

What you really want, I think, is a factory. In it's most naive form, you can say:

public enum WeaponType {
    Fists,
    Sword,
    Bow, 
    Staff
}

public class WeaponFactory {
    public Weapon Create(WeaponType weaponType) {
        switch(weaponType) {
            case WeaponType.Fists:
                return new WeaponFists();

            case WeaponType.Sword:
                return new WeaponSword();

            case WeaponType.Bow:
                return new WeaponBow();

            case WeaponType.Staff:
                return new WeaponStaff();

            default:
                throw new ArgumentOutOfRangeException("weaponType");
        }
    }
}

Now you can say:

var weapon = weaponFactory.Create(WeaponType.Fists);
Sign up to request clarification or add additional context in comments.

Comments

6

No, enums must be an integral type (byte, short, int, long).

What you are trying to do may be achieved like this:

public static class EnumWeapons
{
    public static readonly Weapon Fists = new WeaponFists();
    public static readonly Weapon Sword = new WeaponSword();
    public static readonly Weapon Bow = new WeaponBow();
    public static readonly Weapon Staff = new WeaponStaff();
}

13 Comments

I disagree this is the right way to handle it. This now gives him the same instance of Fists every time he asks for EnumWeapons.Fists. I doubt that is what he really wants.
@Jason -1 because you disagree? That's interesting. I doubt this is what OP wants too but he'll figure it out sooner or later.
@Cicada: If you doubt it is what OP wants too (your words), then you agree with me this is not a good answer. Your retaliatory down vote because you're angry at me is just immature.
@Jason: No. I agree this is not the best solution but maybe it is what OP is looking for. As for the downvote, I'm not mad, I'm just disagreeing with you :)
@Frank Allenby: I'm glad it worked out for you. But in general, it is unreasonable to expect everyone to be able to figure out the right thing from an answer that provides a misleading solution.
|
2

This won't work with enums directly. You could however use a "regular" enum and a Dictionary<EnumWeapons, Weapon> instead to retrieve your Weapon instances by enum value.

1 Comment

Thank you. I thought of doing that but it will be a bit annoying to maintain in the end, I think.
2

You cannot use an enum that way. You can, however, achieve something similar by creating a static class:

public static class AllWeapons
{
    public static readonly Weapon Fists = new WeaponFists();
    // etc
}

Weapon weapon = AllWeapons.Fists;

Comments

2

According to this source integral constants (which invalidates that code on two levels)

You could use syntactic sugar and make it look like an enum using this:

public static class Weapons
{
    Weapon Fists = new WeaponFists(),
    Weapon Sword = new WeaponSword(),
    Weapon Bow = new WeaponBow(),
    Weapon Staff = new WeaponStaff()
}

Comments

2

The code you typed contains objects and that's no longer an enumeration, which is the purpose of the enum construct. I don't want to only repeat what others said so here's a suggestion: You could keep the enum but create a helper method to generate Weapon objects like this:

public enum EnumWeapons
{
    Fists,
    Sword,
    Bow,
    Staff
}

public Weapon EnumWeaponsToWeaponObject(EnumWeapons weapon)
{
        switch (weapon)
        {
            case EnumWeapons.Fists:
                return new FistWeapon();
                break;
            case EnumWeapons.Sword:
                return new SwordWeapon();
                break;
            case EnumWeapons.Bow:
                return new BowWeapon();
                break;
            case EnumWeapons.Staff:
                return new StaffWeapon();
                break;
            default:
                throw new ArgumentException("Not a supported weapon type!");
                break;
        }

}

You can make this method an extension so that you can use it as follows: EnumWeapons.Sword.EnumWeaponsToWeaponObject();

Comments

1

I don't think C# enums works this way. in C# all enum values are basically ints. However you may use your approach:

public class Weapon 
{
    public static readonly Weapon Fists = new WeaponFists();
    public static readonly Weapon Sword = new WeaponSword();
   ...
}

and then

var myWeapon = Weapon.Fists;

Comments

1

As per MSDN, "The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong."

Please see This Reference.

1 Comment

I've read those documents a number of times. I'm puzzled of why it isn't throwing a compiler error when I attempt this?
1

You can use an indexer to refer to an Array or List both by ordinal position and string. Not as clean as enumeration but the Array or List can contain objects. The this is what makes it an indexer.

    namespace Indexer
    {
        class Program
        {
            static void Main(string[] args)
            {
                Persons MyPeople = new Persons();
                Console.WriteLine("MyPeople[0] " + MyPeople[0].Name);
                Console.WriteLine("MyPeople[0] " + MyPeople[1].Name);
                Console.WriteLine("MyPeople[Jim] " + MyPeople["Jim"].Name);
                Console.ReadLine();
            }
        }
        public class Persons
        {
            private List<Person> persons = new List<Person>();
            public int Count { get { return persons.Count; } }

            public Person this[int index]
            {
                get
                {
                    return persons[index];
                }
                set
                {
                    persons[index] = value;
                }
            }
            public Person this[string name]
            {
                get
                {
                    foreach (Person p in persons)
                    {
                        if (p.Name == name) return p;
                    }
                    return null;
                }
            }
            public Persons()
            { 
                persons.Add(new Person("Jim"));
                persons.Add(new Person("Harry"));
            }
            public class Person
            {
                private string name;
                public string Name { get { return name; } }
                public Person(string Name) { name = Name; }
            }
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.