在枚举中使用字符串

本文关键字:字符串 枚举 | 更新日期: 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
}

之后,您只需使用标准反射来获取字段上的自定义属性。

我认为这些答案都没有正确地解决这个问题。这里真正需要的是一个数据库来存储这些数据,这些数据可以随时间而更改。试图将变化的数据存储在代码中通常是一个坏主意,因为它将要求每次数据更改时重新编译。

包含AccountIdAccountName(可能还有其他需要存储的数据)列的数据库表绝对是最健壮的解决方案。如果这只是一个快速和肮脏的应用程序,它甚至不需要是一个完整的数据库,像SQLite或SQL Server Express之类的东西会工作。

然后您可以通过ado.net代码或您选择的对象关系映射器访问此表。