在 C# 中将硬编码字符串替换为常量

本文关键字:字符串 替换 常量 编码字符 编码 | 更新日期: 2023-09-27 17:55:38

我正在尝试获取.cs文件中的所有硬编码字符串并从常量文件中加载它。

例如

string capital="Washington";

应加载为

string capital=Constants.capital;

这将添加到常量中.cs

public final const capital="Washington";

我需要一个java/C#代码片段来执行此操作。我无法使用任何第三方工具。对此有任何帮助吗?

编辑:

阅读评论和答案后,我有一种不清楚的感觉。我只是想要一种方法来替换所有具有"的硬编码常量并将其撕掉并替换为常量。并在 Constants.cs 中添加该属性。这也可以是一个简单的文本处理。

在 C# 中将硬编码字符串替换为常量

一些提示应该让你开始:

假设字符串处理器函数称为进程字符串。

1) 将常量.cs包含在与 ProcessString 函数相同的项目中,以便使用重构代码对其进行编译。

2)反思你的常量类,为常量名称构建语言字符串字典,如下所示:

Dictionary<String, String> constantList = new Dictionary<String, String>();
FieldInfo[] fields = typeof(Constants).GetFields(BindingFlags.Static | BindingFlags.Public);
String constantValue;
foreach (FieldInfo field in fields)
{
    if (field.FieldType == typeof(String))
    {                    
        constantValue = (string)field.GetValue(null);             
        constantList.Add(constantValue, field.Name);
    }
}

3) constantList 现在应该包含常量名称的完整列表,由它们所代表的字符串索引。

4)从文件中获取所有行(使用File.ReadAllLines)。

5)现在迭代线条。 如下所示的内容应该允许您忽略不应处理的行。

//check if the line is a comment or xml comment
if (Regex.IsMatch(lines[idx], @"^'s*//")) 
    continue;
//check if the entry is an attribute
if (Regex.IsMatch(lines[idx], @"^'s*'["))
    continue;
//check if the line is part of a block comment (assuming a * at the start of the line)
if (Regex.IsMatch(lines[idx], @"^'s*(/'*+|'*+)"))
    continue;
//check if the line has been marked as ignored 
//(this is something handy I use to mark a string to be ignored for any reason, just put //IgnoreString at the end of the line)
if (Regex.IsMatch(lines[idx], @"//'s*IgnoreString's*$")) 
    continue;

6)现在,匹配行上任何带引号的字符串,然后检查每个匹配项并检查其几个条件。如果需要,您可以删除其中一些条件。

MatchCollection mC = Regex.Matches(lines[idx], "@?'"([^'"]+)'"");
foreach (Match m in mC)
{                           
    if (            
        // Detect format insertion markers that are on their own and ignore them, 
        !Regex.IsMatch(m.Value, @"""'s*'{'d(:'d+)?'}'s*""") &&
        //or check for strings of single character length that are not proper characters (-, /, etc)
        !Regex.IsMatch(m.Value, @"""'s*''?[^'w]'s*""") &&
        //check for digit only strings, allowing for decimal places and an optional percentage or multiplier indicator
        !Regex.IsMatch(m.Value, @"""['d.]+[%|x]?""") &&
        //check for array indexers
        !(m.Index <= lines[idx].Length && lines[idx][m.Index - 1] == '[' && lines[idx][m.Index + m.Length] == ']')  &&          
        )
    {
        String toCheck = m.Groups[1].Value;
        //look up the string we found in our list of constants
        if (constantList.ContainsKey(toCheck))
        {
            String replaceString;
            replaceString = "Constants." + constants[toCheck];              
            //replace the line in the file
            lines[idx] = lines[idx].Replace("'"" + m.Groups[1].Value + "'"", replaceString);
        }
        else
        {
            //See Point 8....
        }
    }

7)现在重新连接行数组,并将其写回文件。 这应该让你大部分时间。

8)要让它为您还没有条目的字符串生成常量,在用于查找字符串的 else 块中, 从字符串中为常量生成一个名称(我刚刚从字符串中删除了所有特殊字符和空格并将其限制为 10 个单词)。 然后使用该名称和原始字符串(来自第 6 点中的 toCheck 变量)进行常量声明并将其插入 Constants.cs。 然后,当您再次运行该函数时,将使用这些新常量。

我不知道是否有任何这样的代码可用,但我提供了一些关于如何实现它的指南。

  1. 您可以编写宏/独立应用程序(我认为宏是更好的选择)
  2. 分析当前文档或项目/解决方案中的所有文件
  3. 编写一个用于查找字符串的正则表达式(XAML 中的字符串呢?)。 类似 [string]([a-z A-Z0-9])["]([a-z A-Z0-9])["][;]——这是无效的,我只是提供讨论
  4. 从代码中提取常量。
  5. 检查静态类中是否已存在类似的字符串
  6. 如果未找到,则在静态类中插入新条目
  7. 将字符串替换为变量名称
  8. 转到步骤 2
是否有

理由不能将它们放入静态类或仅放入应用程序中的文件中? 您可以将常量放在任何地方,只要它们的作用域正确,您就可以从任何地方访问它们。

public const string capital = "Washington";

如果 const 在静态类中不起作用,那么它将是

public static readonly string capital = "Washington";

如果你真的想按照你描述的方式去做,用流阅读器读取文件,按''r'分割,检查第一件事是否是"字符串",然后对该字符串元素进行所有替换......确保每次更改该字符串声明时,都将 nessesary 行添加到另一个文件中。

可以为常量创建一个类项目,或者如果您有帮助程序类项目,则可以为常量添加新类 ( Constants.cs )。

public static class Constants
{
   public const string CAPITAL_Washington = "Washington";
}

您现在可以使用它:

string capital = Constants.CAPITAL_Washington;

您不妨将常量命名为非常具体。