用C#编写多个构造函数重载的最佳方法



我正在学习C#,并制作了一个简单的"Player"类。但我很难承受多重负荷。这是我最好的解决方案,但我觉得它可以做得更简单/更好。

class Player : Entity
{
public Player() {
Name = "Player";
XP = 0;
LVL = 1;
XPToLvlUp = 10;
XpRank = 10;
}
public Player(string name) : this() {
Name = name;
}
public Player(string name, int _Hp, int _Mp) : this(name) {
HP = _Hp;
MP = _Mp;
}
public Player(string name, int _Hp, int _Mp, int _Xp, int _Lvl) : this(name, _Hp, _Mp) {
XP = _Xp;
LVL = _Lvl;
}
public Player(string name, int _Hp, int _Mp, int _Xp, int _Lvl, int XpByRank) : this(name, _Hp, _Mp, _Xp, _Lvl) {
XpRank = XpByRank;
}
//deleted code for better reading
private int XPToLvlUp;
private int XpRank;
public int XP;
public int LVL;
public string Name;
}  

它好吗?如果不好,请告诉我为什么。感谢您的回复!

我认为这很好。有一个问题要问自己:这些方法中的每一个都可能被调用吗?

一种选择是让程序员在实例化类后设置这些值:

var myPlayer = new Player();
myPlayer.XP = 5;

然而,在某些情况下,你真的想提前了解所有信息,所以这可能不合适。

另一个选项可以是传递给ctor:的选项类

public class PlayerSettings
{
public Name = "Player";
public XP = 0;
public LVL = 1;
public XPToLvlUp = 10;
public XpRank = 10; 
}

然后你的ctors看起来是这样的:

public Player() : this(new PlayerSettings())
{
}
public Player(PlayerSettings settings)
{
//Fill in appropriate variables here
}

该选项将以这种方式调用:

var playerSettings = new PlayerSettings() { XP = 5 };
var myPlayer = new Player(playerSettings());

最后,我不确定其中一个比另一个"更好",这在很大程度上取决于你的需求。

您的类几乎是好的,可以接受。

短篇小说:使用属性。

长话短说:

首先,制定或遵循命名规则,这将使您的代码更易于阅读。这取决于你,只是一个建议。对于由多个单词组成的复杂名称,可以使用CamelCasedNames。在可能有用的地方,避免缩短所有类型数据的名称。例如,您可以将Lvl扩展到Level,但XpExperience看起来有些奇怪。这也取决于你。

string name; // local Variable, first character lower cased
private string _name; // private Field, first character is lower cased with leading "_"
public string Name { get; set; } // public Property, first character is upper cased

我将向您展示替代overriden构造函数的方法,并将遵循命名规则。

1( 构造函数的默认值(使用类的一部分以保持简单(

class Player
{
public Player(string name = "Player", int xp = 0, int level = 1)
{
Name = name;
Xp = xp;
Level = level;
}
// Properties instead of Fields
public int Xp { get; private set; } // restrict modification of the property outside of a class but reading is available
public int Level { get; private set; }
public string Name { get; set; }
} 

2( 不带默认值的构造函数的属性

第一个属性的目的是限制对数据的访问,以保持内部对象数据的一致性。即使你在代码中也会犯错误。避免一些错误的好方法。

第二个属性目的是在获取或设置代码时执行代码。例如,使属性相互依赖以存储更少且仅唯一的数据。

class Player
{
public int Xp { get; private set; } = 0;
public int Level { get; private set; } = 1;
public string Name { get; set; } = "Player";
} 

使用

Player player = new Player() { Name = "KillerPWNZ", Level = 100, Xp = 999999 };

奖金:另一个属性功能

您可以执行getset子句中的任何代码。

让我们假设每个下一个玩家的等级需要比上一个加倍的经验值,但第二个等级需要100经验值。你决定给第一级玩家开1000经验值的发票。很明显,您将需要碰撞Level几次。假设Xp包含相对于Level的值。

发票

player.Xp += 1000;

代码为的房产

private int _xp = 0;
public int Level { get; private set; } = 1;
public int Xp
{
get => _xp; // same as: get { return _xp; }
set
{
_xp = value; // here value is keyword containing data you want to set
while (_xp >= GetXpPerLevel(Level))
{
_xp -= GetXpPerLevel(Level);
Level++;
}
while (_xp < 0 && Level > 1)
{
_xp += GetXpPerLevel(Level - 1);
Level--;
}
}
}
// helper method
private int GetXpPerLevel(int level)
{
if (level < 1) return 0;
// int result = 100;
// for (int i = 1; i < level; i++) result *= 2;
// return result;
// or the same with some binary shift magic :)
return 100 << (level - 1);
}

相关内容

  • 没有找到相关文章

最新更新