最佳实践如何逐行检查行是否包含数组中的字符串并更新知道密钥的 class setter
Best practice how to line by line check if line contains string from array and update a class setter knowing the key
我正在开发一个 Windows 经典桌面应用程序,该应用程序逐行读取 Minecraft Tekkit 设置文件,并将这些行与具有设置键的数组进行比较。如果行中的字符串包含密钥,则应从字符串中删除该密钥,并且应使用生成的变量来更新对象的适当变量。
这是包含要查找的键的字符串数组
static string[] tekkitSettingsKeys = {
"generator-settings=",
"op-permission-level=",
"allow-nether=",
"level-name=",
"enable-query=",
"allow-flight=",
"server-port=",
"level-type=",
"enable-rcon=",
"force-gamemode=",
"level-seed=",
"server-ip=",
"max-build-height=",
"spawn-npcs=",
"white-list=",
"spawn-animals=",
"texture-pack=",
"hardcore=",
"snooper-enabled=",
"online-mode=",
"pvp=",
"difficulty=",
"gamemode=",
"player-idle-timeout=",
"max-players=",
"spawn-monsters=",
"generate-structures=",
"view-distance=",
"motd="
};
这是 TekkitServerSettings class
的变量和吸气剂以及 setters
/*
The settings used to customize world generation. See Superflat and Customized for possible settings and examples.
*/
private string _generatorSettings = String.Empty;
/*
Sets permission level for ops.
1 - Ops can bypass spawn protection.
2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, and /tp, and can edit command blocks.
3 - Ops can use /ban, /deop, /kick, and /op.
4 - Ops can use /stop. DEFAULT
*/
private int _opPermissionLevel = 4;
/*
Allows players to travel to the Nether.
false - Nether portals will not work.
true - The server will allow portals to send players to the Nether.
*/
private bool _allowNether = true;
/*
The "level-name" value will be used as the world name and its folder name. You may also copy your saved game folder here, and change the name to the same as that folder's to load it instead.
Characters such as ' (apostrophe) may need to be escaped by adding a backslash before them.
*/
private string _levelName = "world";
/*
Enables GameSpy4 protocol server listener. Used to get information about server.
*/
private bool _enableQuery = false;
/*
Allows users to use flight on your server while in Survival mode, if they have a mod that provides flight installed.
With allow-flight enabled griefers will possibly be more common, because it will make their work easier. In Creative mode this has no effect.
false - Flight is not allowed (players in air for at least 5 seconds will be kicked).
true - Flight is allowed, and used if the player has a fly mod installed.
*/
private bool _allowFlight = true;
/*
Changes the port the server is hosting (listening) on. This port must be forwarded if the server is hosted in a network using NAT (If you have a home router/firewall).
*/
private int _serverPort = 25565;
/*
Determines the type of map that is generated.
DEFAULT - Standard world with hills, valleys, water, etc.
FLAT - A flat world with no features, meant for building.
LARGEBIOMES - Same as default but all biomes are larger.
AMPLIFIED - Same as default but world-generation height limit is increased.
CUSTOMIZED - Same as default unless generator-settings is set to a preset.
*/
private string _levelType = "DEFAULT";
/*
Enables remote access to the server console.
*/
private bool _enableRcon = false;
/*
Force players to join in the default game mode.
false - Players will join in the gamemode they left in.
true - Players will always join in the default gamemode.
*/
private bool _forceGameMode = false;
/*
Add a seed for your world, as in Singleplayer.
Some examples are: minecraft, 404, 1a2b3c.
*/
private string _levelSeed = String.Empty;
/*
Set this if you want the server to bind to a particular IP. It is strongly recommended that you leave server-ip blank!
Set to blank, or the IP you want your server to run (listen) on.
*/
private string _serverIp = String.Empty;
/*
The maximum height in which building is allowed. Terrain may still naturally generate above a low height limit.
*/
private int _maxBuildHeight = 256;
/*
Determines if villagers will be spawned.
true - Enabled. Villagers will spawn.
false - Disabled. No villagers.
*/
private bool _spawnNpcs = true;
/*
Enables a whitelist on the server.
With a whitelist enabled, users not on the whitelist will be unable to connect. Intended for private servers, such as those for real-life friends or strangers carefully selected via an application process, for example.
false - No white list is used.
true - The file whitelist.json is used to generate the white list.
Note: Ops are automatically white listed, and there is no need to add them to the whitelist.
*/
private bool _whiteList = false;
/*
Determines if animals will be able to spawn.
true - Animals spawn as normal.
false - Animals will immediately vanish.
Tip: if you have major lag, turn this off/set to false.
*/
private bool _spawnAnimals = true;
/*
Server-side texture packs. Provide a link to the zip file */
private string _texturePack = String.Empty;
/*
If set to true, players will be permanently banned if they die.
*/
private bool _hardcore = false;
/*
Sets whether the server sends snoop data regularly to http://snoop.minecraft.net.
false - disable snooping.
true - enable snooping.
*/
private bool _snooperEnabled = true;
/*
Server checks connecting players against minecraft's account database. Only set this to false if your server is not connected to the Internet. Hackers with fake accounts can connect if this is set to false! If minecraft.net is down or inaccessible, no players will be able to connect if this is set to true. Setting this variable to off purposely is called "cracking" a server, and servers that are presently with online mode off are called "cracked" servers, allowing players with unlicensed copies of Minecraft to join.
true - Enabled. The server will assume it has an Internet connection and check every connecting player.
false - Disabled. The server will not attempt to check connecting players.
*/
private bool _onlineMode = true;
/*
Enable PvP on the server. Players shooting themselves with arrows will only receive damage if PvP is enabled.
true - Players will be able to kill each other.
false - Players cannot kill other players (also known as Player versus Environment (PvE)).
Note: Indirect damage sources spawned by players (such as lava, fire, TNT and to some extent water, sand and gravel) will still deal damage to other players.
*/
private bool _pvp = true;
/*
Defines the difficulty (such as damage dealt by mobs and the way hunger and poison affects players) of the server.
0 - Peaceful
1 - Easy
2 - Normal
3 - Hard
*/
private int _difficulty = 1;
/*
Defines the mode of gameplay.
0 - Survival
1 - Creative
2 - Adventure
3 - Spectator
*/
private int _gamemode = 0;
/*
If non-zero, players are kicked from the server if they are idle for more than that many minutes.
Note: Idle time is reset when the server receives one of the following packets:
102 (0x66) WindowClick
108 (0x6c) ButtonClick
130 (0x82) UpdateSign
14 (0xe) BlockDig
15 (0xf) Place
16 (0x10) BlockItemSwitch
18 (0x12) ArmAnimation
19 (0x13) EntityAction
205 (0xcd) ClientCommand
3 (0x3) Chat
7 (0x7) UseEntity
*/
private int _playerIdleTimeout = 0;
/*
The max numbers of players that can play on the server at the same time. Note that if more players are on the server it will use more resources. Note also, admin connections are not counted against the max players.
*/
private int _maxPlayers = 20;
/*
Determines if monsters will be spawned.
true - Enabled. Monsters will appear at night and in the dark.
false - Disabled. No monsters.
This does nothing if difficulty = 0 (peaceful) Unless your difficulty is not set to 0, when a monster can still spawn from a Monster Spawner. Tip: if you have major lag, turn this off/set to false.
*/
private bool _spawnMonsters = true;
/*
Defines whether structures (such as villages) will be generated.
false - Structures will not be generated in new chunks.
true - Structures will be generated in new chunks.
Note: Dungeons will still generate if this is set to false.
*/
private bool _generateStructures = true;
/*
Sets the amount of world data the server sends the client, measured in chunks in each direction of the player (radius, not diameter). It determines the server-side viewing distance. (see Render distance)
10 is the default/recommended. If you have major lag, reduce this value.
*/
private int _viewDistance = 10;
/*
MOTD is short for Message of the day, though you do not need to change it every day. The MOTD is displayed when people join the server.
*/
private string _motd = "A Tekkit Server";
public string GeneratorSettings
{
get { return _generatorSettings; }
set { _generatorSettings = value; }
}
public int OpPermissionLevel
{
get { return _opPermissionLevel; }
set { _opPermissionLevel = value; }
}
public string AllowNether
{
get { return _allowNether ? "true" : "false"; }
set { _allowNether = value == "true" ? true : false; }
}
public string LevelName
{
get { return _levelName; }
set { _levelName = value; }
}
public string EnableQuery
{
get { return _enableQuery ? "true" : "false"; }
set { _enableQuery = value == "true" ? true : false; }
}
public string AllowFlight
{
get { return _allowFlight ? "true" : "false"; }
set { _allowFlight = value == "true" ? true : false; }
}
public int ServerPort
{
get { return _serverPort; }
set { _serverPort = value; }
}
public string LevelType
{
get { return _levelType; }
set { _levelType = value; }
}
public string EnableRcon
{
get { return _enableRcon ? "true" : "false"; }
set { _enableRcon = value == "true" ? true : false; }
}
public string ForceGameMode
{
get { return _forceGameMode ? "true" : "false"; }
set { _forceGameMode = value == "true" ? true : false; }
}
public string LevelSeed
{
get { return _levelSeed; }
set { _levelSeed = value; }
}
public string ServerIp
{
get { return _serverIp; }
set { _serverIp = value; }
}
public int MaxBuildHeight
{
get { return _maxBuildHeight; }
set { _maxBuildHeight = value; }
}
public string SpawnNpcs
{
get { return _spawnNpcs ? "true" : "false"; }
set { _spawnNpcs = value == "true" ? true : false; }
}
public string WhiteList
{
get { return _whiteList ? "true" : "false"; }
set { _whiteList = value == "true" ? true : false; }
}
public string SpawnAnimals
{
get { return _spawnAnimals ? "true" : "false"; }
set { _spawnAnimals = value == "true" ? true : false; }
}
public string TexturePack
{
get { return _texturePack; }
set { _texturePack = value; }
}
public string HardCode
{
get { return _hardcore ? "true" : "false"; }
set { _hardcore = value == "true" ? true : false; }
}
public string SnooperEnabled
{
get { return _snooperEnabled ? "true" : "false"; }
set { _snooperEnabled = value == "true" ? true : false; }
}
public string OnlineMode
{
get { return _onlineMode ? "true" : "false"; }
set { _onlineMode = value == "true" ? true : false; }
}
public string PVP
{
get { return _pvp ? "true" : "false"; }
set { _pvp = value == "true" ? true : false; }
}
public int Difficulty
{
get { return _difficulty; }
set { _difficulty = value; }
}
public int GameMode
{
get { return _gamemode; }
set { _gamemode = value; }
}
public int PlayerIdleTimeout
{
get { return _playerIdleTimeout; }
set { _playerIdleTimeout = value; }
}
public int MaxPlayers
{
get { return _maxPlayers; }
set { _maxPlayers = value; }
}
public string SpawnMonsters
{
get { return _spawnMonsters ? "true" : "false"; }
set { _spawnMonsters = value == "true" ? true : false; }
}
public string GenerateStructures
{
get { return _generateStructures ? "true" : "false"; }
set { _generateStructures = value == "true" ? true : false; }
}
public int ViewDistance
{
get { return _viewDistance; }
set { _viewDistance = value; }
}
public string Motd
{
get { return _motd; }
set { _motd = value; }
}
下面是最终应该读取文件的方法,如果它包含来自 tekkitSettingsKeys 的字符串之一,则逐行检查它,更新 TekkitServerSettings 对象的适当 setter 和 return TekkitServerSettings对象
public static TekkitServerSettings Load(string settingsFilePath)
{
TekkitServerSettings serverSettingsToLoad = new TekkitServerSettings();
string[] linesFromSettingsFile = File.ReadAllLines(settingsFilePath);
foreach (string tekkitSettingsKey in tekkitSettingsKeys)
{
foreach (string lineFromSettingsFile in linesFromSettingsFile)
{
if (lineFromSettingsFile.Contains(tekkitSettingsKey))
{
// Remove the key from the line
var settingValue = lineFromSettingsFile.Replace(tekkitSettingsKey,"");
// update serverSettingsToLoad's value with the appropriate value in an elegant manner.
??
}
}
}
// Check that everything is good
// return the object
}
我必须以某种方式知道我必须更新的 setter,而且我相信有一种更优雅的方法可以完成此操作,而不是制作一堆 if/else 语句或一个巨大的开关?
例子
当它运行第二个 foreach 时,它读取字符串 level-type=DEFAULT
包含 level-type=
。它删除 level-type=
并以 settingValue = "DEFAULT"
结束。
我现在有了值,我知道密钥是 level-type=
。我想以某种方式完成 serverSettingsToLoad.LevelType = "DEFAULT"
等等。
关于如何以最好的方式完成我想要的有什么建议吗?也许我设置它的方式不是最好的方式?
谢谢!
如果你真的想使用 class 来完成它(我个人会使用像@Luaan 的答案这样的字典),那么你几乎肯定需要使用 Reflection实现这一目标。
使用反射,您可以枚举当前 class 实例上的所有字段,找到具有匹配名称的字段并动态设置值。这是一个简短的例子,修改自:https://msdn.microsoft.com/en-us/library/6z33zd7h.aspx
TekkitServerSettings settings = new TekkitServerSettings();
Type type = typeof(settings);
FieldInfo myField = type.GetField("_maxBuildHeight", BindingFlags.NonPublic | BindingFlags.Instance);
myField.SetValue(settings, 55);
您需要研究的重要 class 是 FieldInfo class。
一个简单的字典就可以了:
class TekkitServerSettings
{
private readonly static Dictionary<string, Action<TekkitServerSettings, string>>
_settingSetters =
new Dictionary<string, Action<TekkitServerSettings, string>>()
{
{ "generator-settings=", (s, v) => s.GeneratorSettings = v },
{ "op-permission-level=", (s, v) => s.OpPermissionLevel = int.Parse(v) }
};
public string GeneratorSettings { get; set; }
public int OpPermissionLevel { get; set; }
}
这使您可以通过找到适当的 setter 操作来简单地加载设置。当然,您可能需要一些辅助方法(例如,以您想要的方式处理错误的方法)。
用法就这么简单
if (_settingSetters.ContainsKey(tekkitSettingsKey))
{
_settingSetters[tekkitSettingsKey](serverSettingsToLoad, settingValue);
}
当然,您需要做很多调整。例如,您可能使字典不区分大小写,或者您可能想要添加一些错误处理来告诉用户他的配置文件中有什么问题(例如,“'5' 是 op-permissions-level 的无效值" 或 "'4x' 是 op-permissions-level 的无效值")。
请注意,我假设您正在逐行阅读配置文件,边读边设置任何已知设置。一次又一次地浏览文件只是为了找到其中一个无序行是没有意义的。只需逐行查找,然后在字典中搜索设置 - 它更快、更干净。
我正在开发一个 Windows 经典桌面应用程序,该应用程序逐行读取 Minecraft Tekkit 设置文件,并将这些行与具有设置键的数组进行比较。如果行中的字符串包含密钥,则应从字符串中删除该密钥,并且应使用生成的变量来更新对象的适当变量。
这是包含要查找的键的字符串数组
static string[] tekkitSettingsKeys = {
"generator-settings=",
"op-permission-level=",
"allow-nether=",
"level-name=",
"enable-query=",
"allow-flight=",
"server-port=",
"level-type=",
"enable-rcon=",
"force-gamemode=",
"level-seed=",
"server-ip=",
"max-build-height=",
"spawn-npcs=",
"white-list=",
"spawn-animals=",
"texture-pack=",
"hardcore=",
"snooper-enabled=",
"online-mode=",
"pvp=",
"difficulty=",
"gamemode=",
"player-idle-timeout=",
"max-players=",
"spawn-monsters=",
"generate-structures=",
"view-distance=",
"motd="
};
这是 TekkitServerSettings class
的变量和吸气剂以及 setters /*
The settings used to customize world generation. See Superflat and Customized for possible settings and examples.
*/
private string _generatorSettings = String.Empty;
/*
Sets permission level for ops.
1 - Ops can bypass spawn protection.
2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, and /tp, and can edit command blocks.
3 - Ops can use /ban, /deop, /kick, and /op.
4 - Ops can use /stop. DEFAULT
*/
private int _opPermissionLevel = 4;
/*
Allows players to travel to the Nether.
false - Nether portals will not work.
true - The server will allow portals to send players to the Nether.
*/
private bool _allowNether = true;
/*
The "level-name" value will be used as the world name and its folder name. You may also copy your saved game folder here, and change the name to the same as that folder's to load it instead.
Characters such as ' (apostrophe) may need to be escaped by adding a backslash before them.
*/
private string _levelName = "world";
/*
Enables GameSpy4 protocol server listener. Used to get information about server.
*/
private bool _enableQuery = false;
/*
Allows users to use flight on your server while in Survival mode, if they have a mod that provides flight installed.
With allow-flight enabled griefers will possibly be more common, because it will make their work easier. In Creative mode this has no effect.
false - Flight is not allowed (players in air for at least 5 seconds will be kicked).
true - Flight is allowed, and used if the player has a fly mod installed.
*/
private bool _allowFlight = true;
/*
Changes the port the server is hosting (listening) on. This port must be forwarded if the server is hosted in a network using NAT (If you have a home router/firewall).
*/
private int _serverPort = 25565;
/*
Determines the type of map that is generated.
DEFAULT - Standard world with hills, valleys, water, etc.
FLAT - A flat world with no features, meant for building.
LARGEBIOMES - Same as default but all biomes are larger.
AMPLIFIED - Same as default but world-generation height limit is increased.
CUSTOMIZED - Same as default unless generator-settings is set to a preset.
*/
private string _levelType = "DEFAULT";
/*
Enables remote access to the server console.
*/
private bool _enableRcon = false;
/*
Force players to join in the default game mode.
false - Players will join in the gamemode they left in.
true - Players will always join in the default gamemode.
*/
private bool _forceGameMode = false;
/*
Add a seed for your world, as in Singleplayer.
Some examples are: minecraft, 404, 1a2b3c.
*/
private string _levelSeed = String.Empty;
/*
Set this if you want the server to bind to a particular IP. It is strongly recommended that you leave server-ip blank!
Set to blank, or the IP you want your server to run (listen) on.
*/
private string _serverIp = String.Empty;
/*
The maximum height in which building is allowed. Terrain may still naturally generate above a low height limit.
*/
private int _maxBuildHeight = 256;
/*
Determines if villagers will be spawned.
true - Enabled. Villagers will spawn.
false - Disabled. No villagers.
*/
private bool _spawnNpcs = true;
/*
Enables a whitelist on the server.
With a whitelist enabled, users not on the whitelist will be unable to connect. Intended for private servers, such as those for real-life friends or strangers carefully selected via an application process, for example.
false - No white list is used.
true - The file whitelist.json is used to generate the white list.
Note: Ops are automatically white listed, and there is no need to add them to the whitelist.
*/
private bool _whiteList = false;
/*
Determines if animals will be able to spawn.
true - Animals spawn as normal.
false - Animals will immediately vanish.
Tip: if you have major lag, turn this off/set to false.
*/
private bool _spawnAnimals = true;
/*
Server-side texture packs. Provide a link to the zip file */
private string _texturePack = String.Empty;
/*
If set to true, players will be permanently banned if they die.
*/
private bool _hardcore = false;
/*
Sets whether the server sends snoop data regularly to http://snoop.minecraft.net.
false - disable snooping.
true - enable snooping.
*/
private bool _snooperEnabled = true;
/*
Server checks connecting players against minecraft's account database. Only set this to false if your server is not connected to the Internet. Hackers with fake accounts can connect if this is set to false! If minecraft.net is down or inaccessible, no players will be able to connect if this is set to true. Setting this variable to off purposely is called "cracking" a server, and servers that are presently with online mode off are called "cracked" servers, allowing players with unlicensed copies of Minecraft to join.
true - Enabled. The server will assume it has an Internet connection and check every connecting player.
false - Disabled. The server will not attempt to check connecting players.
*/
private bool _onlineMode = true;
/*
Enable PvP on the server. Players shooting themselves with arrows will only receive damage if PvP is enabled.
true - Players will be able to kill each other.
false - Players cannot kill other players (also known as Player versus Environment (PvE)).
Note: Indirect damage sources spawned by players (such as lava, fire, TNT and to some extent water, sand and gravel) will still deal damage to other players.
*/
private bool _pvp = true;
/*
Defines the difficulty (such as damage dealt by mobs and the way hunger and poison affects players) of the server.
0 - Peaceful
1 - Easy
2 - Normal
3 - Hard
*/
private int _difficulty = 1;
/*
Defines the mode of gameplay.
0 - Survival
1 - Creative
2 - Adventure
3 - Spectator
*/
private int _gamemode = 0;
/*
If non-zero, players are kicked from the server if they are idle for more than that many minutes.
Note: Idle time is reset when the server receives one of the following packets:
102 (0x66) WindowClick
108 (0x6c) ButtonClick
130 (0x82) UpdateSign
14 (0xe) BlockDig
15 (0xf) Place
16 (0x10) BlockItemSwitch
18 (0x12) ArmAnimation
19 (0x13) EntityAction
205 (0xcd) ClientCommand
3 (0x3) Chat
7 (0x7) UseEntity
*/
private int _playerIdleTimeout = 0;
/*
The max numbers of players that can play on the server at the same time. Note that if more players are on the server it will use more resources. Note also, admin connections are not counted against the max players.
*/
private int _maxPlayers = 20;
/*
Determines if monsters will be spawned.
true - Enabled. Monsters will appear at night and in the dark.
false - Disabled. No monsters.
This does nothing if difficulty = 0 (peaceful) Unless your difficulty is not set to 0, when a monster can still spawn from a Monster Spawner. Tip: if you have major lag, turn this off/set to false.
*/
private bool _spawnMonsters = true;
/*
Defines whether structures (such as villages) will be generated.
false - Structures will not be generated in new chunks.
true - Structures will be generated in new chunks.
Note: Dungeons will still generate if this is set to false.
*/
private bool _generateStructures = true;
/*
Sets the amount of world data the server sends the client, measured in chunks in each direction of the player (radius, not diameter). It determines the server-side viewing distance. (see Render distance)
10 is the default/recommended. If you have major lag, reduce this value.
*/
private int _viewDistance = 10;
/*
MOTD is short for Message of the day, though you do not need to change it every day. The MOTD is displayed when people join the server.
*/
private string _motd = "A Tekkit Server";
public string GeneratorSettings
{
get { return _generatorSettings; }
set { _generatorSettings = value; }
}
public int OpPermissionLevel
{
get { return _opPermissionLevel; }
set { _opPermissionLevel = value; }
}
public string AllowNether
{
get { return _allowNether ? "true" : "false"; }
set { _allowNether = value == "true" ? true : false; }
}
public string LevelName
{
get { return _levelName; }
set { _levelName = value; }
}
public string EnableQuery
{
get { return _enableQuery ? "true" : "false"; }
set { _enableQuery = value == "true" ? true : false; }
}
public string AllowFlight
{
get { return _allowFlight ? "true" : "false"; }
set { _allowFlight = value == "true" ? true : false; }
}
public int ServerPort
{
get { return _serverPort; }
set { _serverPort = value; }
}
public string LevelType
{
get { return _levelType; }
set { _levelType = value; }
}
public string EnableRcon
{
get { return _enableRcon ? "true" : "false"; }
set { _enableRcon = value == "true" ? true : false; }
}
public string ForceGameMode
{
get { return _forceGameMode ? "true" : "false"; }
set { _forceGameMode = value == "true" ? true : false; }
}
public string LevelSeed
{
get { return _levelSeed; }
set { _levelSeed = value; }
}
public string ServerIp
{
get { return _serverIp; }
set { _serverIp = value; }
}
public int MaxBuildHeight
{
get { return _maxBuildHeight; }
set { _maxBuildHeight = value; }
}
public string SpawnNpcs
{
get { return _spawnNpcs ? "true" : "false"; }
set { _spawnNpcs = value == "true" ? true : false; }
}
public string WhiteList
{
get { return _whiteList ? "true" : "false"; }
set { _whiteList = value == "true" ? true : false; }
}
public string SpawnAnimals
{
get { return _spawnAnimals ? "true" : "false"; }
set { _spawnAnimals = value == "true" ? true : false; }
}
public string TexturePack
{
get { return _texturePack; }
set { _texturePack = value; }
}
public string HardCode
{
get { return _hardcore ? "true" : "false"; }
set { _hardcore = value == "true" ? true : false; }
}
public string SnooperEnabled
{
get { return _snooperEnabled ? "true" : "false"; }
set { _snooperEnabled = value == "true" ? true : false; }
}
public string OnlineMode
{
get { return _onlineMode ? "true" : "false"; }
set { _onlineMode = value == "true" ? true : false; }
}
public string PVP
{
get { return _pvp ? "true" : "false"; }
set { _pvp = value == "true" ? true : false; }
}
public int Difficulty
{
get { return _difficulty; }
set { _difficulty = value; }
}
public int GameMode
{
get { return _gamemode; }
set { _gamemode = value; }
}
public int PlayerIdleTimeout
{
get { return _playerIdleTimeout; }
set { _playerIdleTimeout = value; }
}
public int MaxPlayers
{
get { return _maxPlayers; }
set { _maxPlayers = value; }
}
public string SpawnMonsters
{
get { return _spawnMonsters ? "true" : "false"; }
set { _spawnMonsters = value == "true" ? true : false; }
}
public string GenerateStructures
{
get { return _generateStructures ? "true" : "false"; }
set { _generateStructures = value == "true" ? true : false; }
}
public int ViewDistance
{
get { return _viewDistance; }
set { _viewDistance = value; }
}
public string Motd
{
get { return _motd; }
set { _motd = value; }
}
下面是最终应该读取文件的方法,如果它包含来自 tekkitSettingsKeys 的字符串之一,则逐行检查它,更新 TekkitServerSettings 对象的适当 setter 和 return TekkitServerSettings对象
public static TekkitServerSettings Load(string settingsFilePath)
{
TekkitServerSettings serverSettingsToLoad = new TekkitServerSettings();
string[] linesFromSettingsFile = File.ReadAllLines(settingsFilePath);
foreach (string tekkitSettingsKey in tekkitSettingsKeys)
{
foreach (string lineFromSettingsFile in linesFromSettingsFile)
{
if (lineFromSettingsFile.Contains(tekkitSettingsKey))
{
// Remove the key from the line
var settingValue = lineFromSettingsFile.Replace(tekkitSettingsKey,"");
// update serverSettingsToLoad's value with the appropriate value in an elegant manner.
??
}
}
}
// Check that everything is good
// return the object
}
我必须以某种方式知道我必须更新的 setter,而且我相信有一种更优雅的方法可以完成此操作,而不是制作一堆 if/else 语句或一个巨大的开关?
例子
当它运行第二个 foreach 时,它读取字符串 level-type=DEFAULT
包含 level-type=
。它删除 level-type=
并以 settingValue = "DEFAULT"
结束。
我现在有了值,我知道密钥是 level-type=
。我想以某种方式完成 serverSettingsToLoad.LevelType = "DEFAULT"
等等。
关于如何以最好的方式完成我想要的有什么建议吗?也许我设置它的方式不是最好的方式?
谢谢!
如果你真的想使用 class 来完成它(我个人会使用像@Luaan 的答案这样的字典),那么你几乎肯定需要使用 Reflection实现这一目标。
使用反射,您可以枚举当前 class 实例上的所有字段,找到具有匹配名称的字段并动态设置值。这是一个简短的例子,修改自:https://msdn.microsoft.com/en-us/library/6z33zd7h.aspx
TekkitServerSettings settings = new TekkitServerSettings();
Type type = typeof(settings);
FieldInfo myField = type.GetField("_maxBuildHeight", BindingFlags.NonPublic | BindingFlags.Instance);
myField.SetValue(settings, 55);
您需要研究的重要 class 是 FieldInfo class。
一个简单的字典就可以了:
class TekkitServerSettings
{
private readonly static Dictionary<string, Action<TekkitServerSettings, string>>
_settingSetters =
new Dictionary<string, Action<TekkitServerSettings, string>>()
{
{ "generator-settings=", (s, v) => s.GeneratorSettings = v },
{ "op-permission-level=", (s, v) => s.OpPermissionLevel = int.Parse(v) }
};
public string GeneratorSettings { get; set; }
public int OpPermissionLevel { get; set; }
}
这使您可以通过找到适当的 setter 操作来简单地加载设置。当然,您可能需要一些辅助方法(例如,以您想要的方式处理错误的方法)。
用法就这么简单
if (_settingSetters.ContainsKey(tekkitSettingsKey))
{
_settingSetters[tekkitSettingsKey](serverSettingsToLoad, settingValue);
}
当然,您需要做很多调整。例如,您可能使字典不区分大小写,或者您可能想要添加一些错误处理来告诉用户他的配置文件中有什么问题(例如,“'5' 是 op-permissions-level 的无效值" 或 "'4x' 是 op-permissions-level 的无效值")。
请注意,我假设您正在逐行阅读配置文件,边读边设置任何已知设置。一次又一次地浏览文件只是为了找到其中一个无序行是没有意义的。只需逐行查找,然后在字典中搜索设置 - 它更快、更干净。