2011-10-12 9 views
6

Esto es menor, lo sé, pero digamos que tengo una clase de carácter y una clase (sobre todo porque eso es en lo que estoy trabajando). El personaje de clase tiene seis habilidades (tan típico D & D ...). básicamente:Cómo crear una asignación simplificada o propiedad predeterminada para una clase en C#

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 
} 

y

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

Cuando en realidad el uso de estas propiedades de habilidad en el código futuro, me gustaría ser capaz de defecto sólo la puntuación, así:

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

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

en lugar de:

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

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

Ahora, el primer caso se puede resolver con una conversión implícita:

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

¿Alguien me puede ayudar con el reverso? La conversión implícita de esta manera:

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

reemplazará todo el atributo en lugar de sólo la puntuación del atributo — no el resultado deseado ...

+1

Como que realmente * * algo que desea hacer? ¿Es válida una habilidad sin nombre ni abreviatura? Tendrá que recordar que nunca puede almacenar estas habilidades 'int to Ability' porque carecen de datos de visualización. –

+0

Es un buen punto, Ed. Respuesta corta, no realmente (particularmente porque el nombre y la localización de la falta de Abbr en algún momento). El ejemplo se encuentra, sin embargo, porque también necesitaré agregar propiedades "Bonus", "CurScore" y "CurMod" a Ability. –

+0

Si tu clase de personaje era estática, eso sería fácil de hacer. Obviamente, debe tener varios caracteres para que no pueda ser estático. – GianT971

Respuesta

3

En primer lugar, mantener su conversión implícita:

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

Luego en su clase de carácter: Agregue un atributo de Capacidad privado para str, y cambie el captador y el colocador de la propiedad Str como sigue:

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

hay que ir :)

También es posible usar:

   if(string.IsNullOrWhiteSpace(value.Name)) 

en lugar de

   if (value.Name == "") 

Si está compilando a .NET 4.0 versión

EDITAR : Te di una solución que hace exactamente lo que quería, pero lo que ja72 escribió también es una buena sugerencia para los operadores + y -; Puedes agregar su solución a la mía (o mía a él, lo que sea), funcionará bien. A continuación, será capaz de escribir:

 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 
+0

Esto es excelente. No puedo creer que no haya pensado en eso, yo mismo. Pero entonces, esa es la marca de una buena respuesta, ¿no? :) –

+1

Gracias :-) Estoy descubriendo que me encanta ayudar a las personas a resolver problemas de programación, tal vez sea lo que haré en mi próximo trabajo, quién sabe ^^ – GianT971

4

Lo mejor que puede hacer es incrementar la puntuación mediante la adición de estos métodos para Ability.

public static Ability operator + (Ability lhs, int score) 
    { 
     lhs.Score += score; 
     return lhs; 
    } 

    public static Ability operator - (Ability lhs, int score) 
    { 
     lhs.Score -= score; 
     return lhs; 
    } 

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

y utilizarlos como:

static void Main(string[] args) 
    { 
     Character evil = new Character(); //Str.Sccore=10 

     evil.Str += 10; //cast spell for Str.Sccore=20 

     evil.Str -= evil.Str; //death with Str.Sccore=0 
    } 
+0

+1, así es como lo haría. –

+0

Realmente no respondes la pregunta que hizo, pero es un muy buen consejo. Creo que debería usar ambas soluciones en una, ya que podría querer establecer la capacidad de fuerza en algunos casos, en lugar de agregar o quitar puntos de habilidad. Lo probé y funciona bien con ambas soluciones. – GianT971

+0

Esto es extremadamente útil y estoy agradecido por la respuesta. Gian's hace exactamente lo que necesito, así que lo aceptaré, pero fue una decisión difícil para este. Me alegro de que obtenga votos comparables. Merece hacerlo. –

1

Otra opción es reemplazar las propiedades con los delegados como esto

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

    #region Abilities 
    ... 
    #endregion 

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

} 

y utilizar de esta manera

 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 
     } 
0

Tal vez podrías hacer Ability abstracta y luego derivar nuevas clases de Ability para cada una de las sub-clases: Strength, ...

El constructor de la clase Strength sería algo como esto:

public Strength() : base ("Strength", "Str") { ...} 

Ahora las propiedades de capacidad un Character se escribiría fuertemente y las conversiones implícitas podrían convertir un valor como 5 en un objeto Strength con un valor de 5. Esto también evitaría que accidentalmente se guarde un Dexterity en una propiedad Strength, por ejemplo.

[Suponiendo que el nombre y abreviaturas se fija, de hecho, para todos los objetos de ese tipo.]

Cuestiones relacionadas