tags:

views:

115

answers:

4

I have an attribute in my car class called VehicleType.

Using an enum, I could list the different types of cars that exist and not allow any other type to be hard written in.

Problem is, if I have to GET the attribute from somewhere else, I will GET a numberical value, and not the string literal I saved.

What should I use here?

class Hero
{
    public string faction;
    public string name;
    public string herotype;

    enum HeroType
    {
        Agility,
        Strength,
        Intelligence,
    }
}
+3  A: 

You could create an abstract base class

public abstract class BaseHero
{
    public string faction;
    public string name;
    ...... more properties
} 

and then derive your heroes from that:

public class AgilityHero : BaseHero
{
} 

public class StrengthHero : BaseHero
{
} 

public class IntelligenceHero : BaseHero
{
} 

Common stuff would be handled and coded in the base class, those things specific to a hero type in the actual hero class.

Using this OO approach, you can save yourself from having to write, code, maintain a lot of if....then.....else or switch statements in your Hero class - the differences are handled by the fact of having different types for each type of hero.

marc_s
I was thinking this too, but thinking of Warcraft 3, there really isn't any difference in these heroes other than their primary attribute? It really depends on if he actually needs to add specific methods/properties for each hero "type"
Mark
Great answer, and I can see why you suggeted abstract classes. A small car might have heated seats, a huge semi might not even come with one so that would mean a blank attribute. I should have said though, that the HeroType is going to be used strictly as a means to filter what Images are shown. So if ten cars are shown on the form, if someone goes 'Show me the Agility heroes', all others will set the .Visible to false.
Sergio Tapia
This is an excellent method, but how would you handle changing the type of Hero if that ever becomes a requirement?
Jim Schubert
@Papuccino: ok, maybe for now - even so: just put a property on each BaseHero-descendant which defines which picture to show. Chances are, over time, more functionality / properties will be hero-type-specific - and then you have a sound, proven design to work with.
marc_s
@Jim: you'll need a `HeroConverter` class of some sort.
marc_s
@Marc: Yeah, I won't take the easy road. I'll take a little extra time to future-proof my application. I'd hate to have everything break if the game developers decide to add functionality to a type of hero and not the others.
Sergio Tapia
+3  A: 

What? Why would you have a string literal and an enum? Your class should look like this:

class Hero
{
    public string faction;
    public string name;
    public HeroType herotype; // <-- not a string

    enum HeroType
    {
        Agility,
        Strength,
        Intelligence,
    }
}

The "string" version is just the enum so it's easier for you to remember, but shouldn't actually be saved as a string anywhere (except if you need to display it to the user).

Mark
Yep, I caught that when I came back to the PC. Hehe.
Sergio Tapia
A: 

What I sometimes do for modeling richer 'enumeration-like' types is the following:

public enum HeroTypeValue
{
    Agility,
    Strength,
    Intelligence   
}


public class HeroType
{
    public HeroTypeValue Value { get; set; }
    public string Description { get; set; }

    // ... other properties and possibly behaviour, as needed

    public static HeroType Agility = new HeroType 
                           { 
                              ID = HeroTypeValue.Agility, 
                              Description = "Agility" 
                           },

    public static HeroType Strength = new HeroType
                           { 
                              ID = HeroTypeValue.Strength, 
                              Description = "Agility" 
                           };

    public static HeroType Intelligence = new HeroType 
                           { 
                              ID = HeroTypeValue. Intelligence, 
                              Description = "Intelligence" 
                           };

    public static IEnumerable<HeroType> All = new [] 
    {
        Agility,
        Strength,
        Intelligence
    }
}

This allows to do data binding with easily customizable descriptions, when needed you can also synchronize with a table in the database.

You can of course combine it with the answer by marc_s, making the HeroType a (abstract or not) base class for added OO value.

jeroenh
+1  A: 

Whether an enum is approriate depends entirely on your design. If you have a fixed number of possible values, then an enum may be a good approach.

In C# you can convert between an Enumerated type and its string representation using Enum.ToString() and Enum.Parse(), so it is trivially easy to serialise an enum's value and disallow "illegal" values when reloading the data. There is no need to serialise it as an integer value.

(The one caveat of this is if you use obfuscation, you must make sure not to obfuscate the enumerated type)

If you have to store the enum as an integer value, then there is no problem with that, as long as you don't change the values of the enum entries - add new entries at the end of the enum's list, but don't insert new entries in the middle of it.

Jason Williams