在枚举中使用字符串
本文关键字:字符串 枚举 | 更新日期: 2023-09-27 18:17:51
我有一个标准的c#枚举来表示银行账户:
public enum Accounts
{
BankOfAmerica = 123654,
BankOfIndia = 765091
}
这个枚举在我的代码中的许多地方使用。一些对象使用它来将帐号作为字符串("123654")、整数(123654)或帐户名称作为字符串("BankOfAmerica")使用。
帐户号码变化,它们也包含数字,因此我不能简单地改变enum…
谁能指出一种方法,使这个变化尽可能的痛苦,在代码中的更改数量最少?
我想用包含帐户名称和值的单例类替换枚举,但是随后需要进行许多代码更改才能用新类替换旧枚举的使用。
帐号改变了,其中也包含数字…
那你用错工具了。枚举类型的值应该在编译时定义。如果帐号改变了,那么你应该使用一个更高级的类型(例如,一个类),它将允许突变(如果需要),并且还可以为UI层提供更高级的格式。
Ed S.是正确的;枚举不是适合这项工作的工具。详细说明他的回答:
枚举值是常量,并且要求常量在所有时间逻辑上都是常量,包括过去、现在和将来。如果枚举值可以随时间改变而其意义不变,那么它首先就不应该是enum或const。
类似地,如果enum中的元素可以随时间改变,即使它们的值保持不变,那么使用enum可能是个坏主意。你不希望出现这种情况:enum Banks
{
BankOfFoo,
BankOfBar,
BankOfBlah,
BankOfABC
}
然后下一个版本,Foo银行收购了Bar银行,Blah银行倒闭了,ABC银行改名为DEF银行,一个全新的XYZ银行成立了。
枚举是表示随时间变化的内容的错误机制。您不应该为此使用enum,也不应该使用const string。
var accounts = new Dictionary<string,string>();
accounts.Add("Bank of America", "ABC12345");
accounts.Add("Bank of India", "122-6X-666");
string number = accounts["Bank of America"];
或者,如果您喜欢使用enum:
public enum Accounts {
BankOfAmerica,
BankOfIndia
}
var accounts = new Dictionary<Accounts,string>();
accounts.Add(Accounts.BankOfAmerica, "ABC12345");
accounts.Add(Accounts.BankOfIndia, "122-6X-666");
string number = accounts[Accounts.BankOfAmerica];
最好为BankAccount使用一个类,如下所示:
public class BankAccount
{
public string Name { get; set; }
public int Number { get; set;}
public BankAccount(string name, int number)
{
Name = name;
Number = number;
}
}
然后在集合中持有实际帐户,如List:
public List<BankAccount> BankAccounts = new List<BankAccount>();
然后你可以很容易地通过号码或名字搜索银行账户,或者通过使用循环或LINQ:
查找任何属性public BankAccount GetAccountByName(string name)
{
return BankAccounts.FirstOrDefault(a => a.Name == name);
}
当您找到想要更改的BankAccount对象时,只需更改属性:
var account = GetAccountByName("BankOfAmerica");
account.Number = 12345678;
或者通过创建一个方法来完成。枚举不是解决这个问题的方法;它们是一组常量,必须在编译时定义,并且不能更改。即使需要花费大量时间来实现这样的更改,但从长远来看,这是值得的,并且只会使事情变得更容易。
为什么不使用Attributes呢?
class AccountAttribute : Attribute
{
public string MyValue { get; set; }
// add any other stuff...
}
public enum Accounts
{
[Account(MyValue = "A")]
BankOfAmerica = 123654,
[Account(MyValue = "B")]
BankOfIndia = 765091
}
之后,您只需使用标准反射来获取字段上的自定义属性。
我认为这些答案都没有正确地解决这个问题。这里真正需要的是一个数据库来存储这些数据,这些数据可以随时间而更改。试图将变化的数据存储在代码中通常是一个坏主意,因为它将要求每次数据更改时重新编译。
包含AccountId、AccountName(可能还有其他需要存储的数据)列的数据库表绝对是最健壮的解决方案。如果这只是一个快速和肮脏的应用程序,它甚至不需要是一个完整的数据库,像SQLite或SQL Server Express之类的东西会工作。
然后您可以通过ado.net代码或您选择的对象关系映射器访问此表。