在 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 中添加该属性。这也可以是一个简单的文本处理。
一些提示应该让你开始:
假设字符串处理器函数称为进程字符串。
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。 然后,当您再次运行该函数时,将使用这些新常量。
我不知道是否有任何这样的代码可用,但我提供了一些关于如何实现它的指南。
- 您可以编写宏/独立应用程序(我认为宏是更好的选择)
- 分析当前文档或项目/解决方案中的所有文件
- 编写一个用于查找字符串的正则表达式(XAML 中的字符串呢?)。 类似 [string]([a-z A-Z0-9])["]([a-z A-Z0-9])["][;]——这是无效的,我只是提供讨论
- 从代码中提取常量。
- 检查静态类中是否已存在类似的字符串
- 如果未找到,则在静态类中插入新条目
- 将字符串替换为变量名称
- 转到步骤 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;
您不妨将常量命名为非常具体。