在代码中使用大量硬编码字符串

时间:2012-02-29 15:29:04

标签: c#

当我查看我的代码时,我正在编写类似的东西。

if (role == "Customer")
{
    bCustomer = true;
}
else if (role == "Branch")
{
    bIsBranch = true;
}

或者

foreach(DataRow as row in myDataSet.Tables[0].Rows)
{
    row["someField"]=somefield.Tostring()
}

你们这样做吗?什么时候可以做,什么时候不应该这样做?如果有任何更好的方法来写这个怎么办?

感谢评论:我想我应该添加if(为了这个示例目的)我只使用此角色比较一次?创建一个全新的课程仍然是一个更好的主意吗?我是否应该有一个名为“常量”的类是多个具有特定常量的类,例如“roles”类?

8 个答案:

答案 0 :(得分:28)

没有。不要使用“magic strings”。而是创建一个包含常量的静态类,或者如果可以的话创建一​​个枚举。

例如:

public static class Roles
{
  public const string Customer = "Customer";
  public const string Branch = "Branch";
}

用法:

if (role == Roles.Customer)
{

}
else if (role == Roles.Branch)
{

}

这是good discussion on various solutions

答案 1 :(得分:2)

最好将硬编码字符串分别声明为常量,而不是每次都声明一个新字符串。它可以保持代码清洁并减少因输入错误而导致的错误。

关于应该或不应该完全取决于场景。

答案 2 :(得分:2)

我会制作一个Roles静态类:

public sealed class Roles
{
    public const string BRANCH = "Branch";
    public const string CUSTOMER = "Customer";

    public static bool IsCustomer(string role)
    {
        return role == CUSTOMER;
    }
}

然后在你的代码中:

bCustomer = Roles.IsCustomer(role);

或者,这需要更多设置,但RoleProvder(取决于Web或不依赖)提供了许多好方法。

答案 3 :(得分:2)

我认为更好的方法是使用application settings,这意味着如果“Customer”或“Branch”值发生变化,您将不需要重新编译代码。魔术值明显不好,这将是一个很好的第一步/选择远离他们。此外,它将您的值保存在一个位置,我也相信您可以在运行时reload the settings而无需重新启动应用程序(尽管我自己没有尝试过)。

E.g:

if (role == Properties.Settings.Default.CustomerRole) 
{     
    bCustomer = true; 
} 
else if (role == Properties.Settings.Default.BranchRole) 
{    
    bIsBranch = true; 
} 

答案 4 :(得分:0)

嗯,在我看来,这取决于你,这取决于你的应用程序设计。 我从积极的方面看待它 - 如果应用程序按照它应该的方式工作,那一切都很好。 IMHO

答案 5 :(得分:0)

Polimorphism是一回事,但在代码中使用硬编码字符串并不是很好。最好定义一个包含字符串的变量,并在代码中使用这个变量。这种情况如果你需要改变一些东西(相信我你会),你可以改变这个变量的值并完成它(也减少错误!)

答案 6 :(得分:0)

为了可维护性,您应尽可能将字符串比较器形式化为命名常量或枚举。程序员的好处是可以本地化更改。即使使用重构工具,查找使用字符串的所有位置也可能很乏味且容易出错。您今天可能只有一个地方在进行此比较,但您或未来的维护者可能会将此扩展到代码的其他部分。此外,班级本身可能会增长,需要分开。随着时间的推移,这些事情往往会逐渐增加。

我只是将这些字符串声明为接近它们使用位置的常量,但是它们在一起。在你知道自己需要它之前,不要再使用像Roles这样的新抽象。如果需要比较的角色数量增长,或者在此类之外需要,则可以创建Roles枚举或角色类,具体取决于比较的复杂程度。

此外,通过使用常量,您可以向编译器发出预期用途的信号,因此您可以获得一些较小的内存管理优势,如果您的比较处于循环中,这通常是一种很好的做法。

答案 7 :(得分:0)

使用 nameof 表达式消除 C# 代码中魔术字符串的使用

使用 nameof expression,您可以检索 typesclasses、{文字大小写 {1}}、structspropertiesmethodsfunctionsfieldsargumentsparameters 等它们在编译时出现在代码中的大小写。这不会消除或解决您所有的“魔法字符串”问题,但它是一个好的开始,值得讨论。

例如,获取 locals 值的文字大小写

enum

nameof 用法

public enum ExportType
{
   CSV,
   Excel
}

返回参数中表达式的文字大小写

不再有“魔法弦”

如果您指的是特定 nameof(ExportType.CSV); // "CSV" nameof(ExportType.Excel); // "Excel" nameof(ExportType); // "ExportType" type namesclasses 的代号,请强烈考虑用 etc. 替换那些脆弱的魔法字符串。您不会害怕更改内部类型或属性的名称,而不必担心会破坏代码。使用重命名功能,如 Visual Studio 的 IDE 将重命名代码库中任何位置引用该表达式的所有引用。

类型安全

此操作在编译时完成。最后,如果您依赖代码中的 nameoftypesclasses 名称,您可以引入编译时类型安全 在引用它们时进入您的逻辑。

性能

您还可以消除代码中的大量反射,从而获取这些东西的名称

警告

获取泛型名称

etc.

在这些情况下,您必须在运行时继续使用反射来获取类型的名称。 nameof(T); // "T" nameof(TEntity); // "TEntity" 不幸的是不是很有用。

例如:

nameof