[英]Best way to write multiple constructor overloads in C#
I am learning C# and made a simple "Player" class.我正在学习 C# 并制作了一个简单的“播放器”class。 But I struggle having multiple overload.
但我很难有多重超载。 Here's my best solution but I feel like it could be done simpler/better.
这是我最好的解决方案,但我觉得它可以做得更简单/更好。
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;
}
Is it good and if not please tell me why.好不好,如果不好请告诉我为什么。 Thanks for your responses!
感谢您的回复!
I think it's fine as is.我认为这很好。 One question to ask yourself: Are each of those methods actually likely to be called?
要问自己一个问题:这些方法中的每一个是否真的可能被调用?
One option is to just let the programmer set those values after they've instantiated the class:一种选择是让程序员在实例化 class 后设置这些值:
var myPlayer = new Player();
myPlayer.XP = 5;
However, there are situations where you really want all the info up front, so that may not be suitable.但是,在某些情况下,您确实需要预先了解所有信息,因此这可能不合适。
Another option could be an options class that is passed to the ctor:另一个选项可能是传递给 ctor 的选项 class:
public class PlayerSettings
{
public Name = "Player";
public XP = 0;
public LVL = 1;
public XPToLvlUp = 10;
public XpRank = 10;
}
Then your ctors looks like this:然后你的ctors看起来像这样:
public Player() : this(new PlayerSettings())
{
}
public Player(PlayerSettings settings)
{
//Fill in appropriate variables here
}
That option would be called in this way:将以这种方式调用该选项:
var playerSettings = new PlayerSettings() { XP = 5 };
var myPlayer = new Player(playerSettings());
In the end, I'm not sure one is "better" than the other, it largely depends on your needs.最后,我不确定一个是否比另一个“更好”,这在很大程度上取决于您的需求。
Your class is almost good and acceptable.您的 class 几乎可以接受。
Short story: use Properties.短篇小说:使用属性。
Long story:很长的故事:
First of all make or follow the naming rules, it will make your code more friendly to read.首先制定或遵循命名规则,它会让你的代码更易于阅读。 It's up to you, just a suggestion.
这取决于你,只是一个建议。 For complex names consisting of multiple words you may use
CamelCasedNames
.对于由多个单词组成的复杂名称,您可以使用
CamelCasedNames
。 And avoid shorten names for all types of data where it maybe useful.并避免在可能有用的地方缩短所有类型数据的名称。 For example you may expand
Lvl
to Level
but Xp
to Experience
will look as something odd.例如,您可以将
Lvl
扩展到Level
,但将Xp
扩展到Experience
看起来会很奇怪。 It's up to you too.这也取决于你。
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
I'll show you alternatives to overriden constructors and will follow the naming rules.我将向您展示替代构造函数的替代方法,并将遵循命名规则。
1) Default values for constructor (with a part of your class to keep it simple) 1)构造函数的默认值(使用 class 的一部分保持简单)
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) Properties without constructor with default values 2) 没有带有默认值的构造函数的属性
First Property purpose is restrict access to data to keep internal object data consistent.第一个属性的目的是限制对数据的访问,以保持内部 object 数据一致。 Even you make mistakes in the code.
即使你在代码中犯了错误。 Good way to avoid some bugs.
避免一些错误的好方法。
Second property purpose is executing code while you're getting or setting one.第二个属性目的是在获取或设置代码时执行代码。 For example, making properties dependent on each other to store less and only unique data.
例如,使属性相互依赖以存储更少且仅唯一的数据。
class Player
{
public int Xp { get; private set; } = 0;
public int Level { get; private set; } = 1;
public string Name { get; set; } = "Player";
}
Usage用法
Player player = new Player() { Name = "KillerPWNZ", Level = 100, Xp = 999999 };
Bonus: Another Property feature奖金:另一个属性功能
You can execute any code in get
or set
clause.您可以在
get
或set
子句中执行任何代码。
Let's assume that each next player's level require doubled amount of xp from previous but 2nd level requre 100 XP.假设每个下一个玩家的级别需要双倍的经验值,但第二级需要 100 经验值。 And you decided to invoice to the 1st leveled player 1000 XP.
你决定向第一级玩家开具 1000 XP 的发票。 Obviously you'll need to bump the
Level
few times.显然,您需要多次调整
Level
。 Assuming that Xp
contains relative to Level
value.假设
Xp
包含相对于Level
的值。
The invoice发票
player.Xp += 1000;
The Property with code带有代码的属性
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.