Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a simplified assignment or default property for a class in C#

Tags:

c#

This is minor, I know, but let's say that I have a class Character and a class Ability (mostly because that's what I'm working on). Class Character has six abilities (so typical D&D...). basically:

public class Character
{
    public Character()
    {
        this.Str = new Ability("Strength", "Str");
        this.Dex = new Ability("Dexterity", "Dex");
        this.Con = new Ability("Constitution", "Con");
        this.Int = new Ability("Intelligence", "Int");
        this.Wis = new Ability("Wisdom", "Wis");
        this.Cha = new Ability("Charisma", "Cha");
    }

    #region Abilities
    public Ability Str { get; set; }
    public Ability Dex { get; set; }
    public Ability Con { get; set; }
    public Ability Int { get; set; }
    public Ability Wis { get; set; }
    public Ability Cha { get; set; }
    #endregion
}

and

public class Ability
{
    public Ability()
    {
        Score = 10;
    }
    public Ability(string Name, string Abbr)
        : this()
    {
        this.Name = Name;
        this.Abbr = Abbr;
    }

    public string Name { get; set; }
    public string Abbr { get; set; }
    public int Score { get; set; }
    public int Mod
    {
        get
        {
            return (Score - 10) / 2;
        }
    }
}

When actually using these ability properties in future code, I'd like to be able to default to just the score, like so:

//Conan hits someone
int damage = RollDice("2d6") + Conan.Str;

//evil sorcerer attack drains strength
Conan.Str = 0;

rather than:

//Conan hits someone
int damage = RollDie("2d6") + Conan.Str.Score;

//evil sorcerer attack drains strength
Conan.Str.Score = 0;

Now, the first case can be taken care of with an implicit conversion:

public static implicit operator int(Ability a)
{
    return a.Score;
}

Can anybody help me with the reverse? Implicit conversion like this:

public static implicit operator Ability(int a)
{
    return new Ability(){ Score = a };
}

will replace the entire attribute rather than just the score of the attribute—not the desired result...

like image 495
Jacob Proffitt Avatar asked Oct 12 '11 23:10

Jacob Proffitt


People also ask

How do I set default value in property?

Right-click the control that you want to change, and then click Properties or press F4. Click the All tab in the property sheet, locate the Default Value property, and then enter your default value. Press CTRL+S to save your changes.

What is a class property in C#?

Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code. A get property accessor is used to return the property value, and a set property accessor is used to assign a new value.

Can we have private properties in C#?

Properties can be marked as public , private , protected , internal , protected internal , or private protected . These access modifiers define how users of the class can access the property. The get and set accessors for the same property may have different access modifiers.


2 Answers

Another option is to replace the properties with delegates like this

public class Character
{
    public Character()
    {
        ...
    }

    #region Abilities
    ...
    #endregion

    public Func<int> Strength
    {
        get { return () => Str.Score; }
        set { Str.Score = value(); }
    }

}

and use it like this

        Character evil = new Character(); //Str.Sccore=10
        // fist spell hits
        evil.Strength = () => 5; //set Str.Score=5
        // second spell hits
        evil.Strength = () => 0; //set Str.Score=5

        if (evil.Strength() == 0)
        {
            // dead
        }
like image 98
John Alexiou Avatar answered Oct 21 '22 04:10

John Alexiou


First, keep your implicit conversion:

public static implicit operator Ability(int a)
{
     return new Ability(){ Score = a };
}

Then in your character class: Add a private Ability attribute for str, and change the getter and the setter of the Str property as follows:

    private Ability str;
    public Ability Str 
    {
        get
        {
            return this.str;
        }
        set
        {
            if (value.Name == "")
            {
                this.str.Score = value.Score;
            }
            else
            {
                this.str = value;
            }
        }
    }

There you go :)

You could also use:

                if(string.IsNullOrWhiteSpace(value.Name))

instead of

                if (value.Name == "")

If you are compiling to .NET 4.0 version

EDIT: I gave you a solution that does exactly what you wanted to, but What ja72 wrote is also a good suggestion with operators + and -; you can add his solution to mine (or mine to him, whatever), it will work just fine. You will then be able to write:

        Character Jax = new Character(); // Str.Score = 10
        Character Conan = new Character(); // Str.Score = 10

        Jax.Str = 2000; // Str.Score = 2000;
        Conan.Str += 150; // Str.Score = 160
like image 3
GianT971 Avatar answered Oct 21 '22 03:10

GianT971