据我所知,作者本人对标题中的论点进行了如下解释:“如果一个函数仅执行所声明的函数名称下处于同一抽象级别的那些操作,则该函数执行一个操作。 ” 由于我最近才学习编程(2个月),我请有知识的人用一个简单的例子来解释它应该是什么样子:
有一个方法(从 Main 方法调用)需要两行并返回第三行,其中包含在源行中找不到的文本(实际上有点复杂,但为了示例起见,这个解释就足够了) )。在该方法内部,根据特定关键字将源字符串拆分为两个列表,然后确定两个列表的交集并依次从每个列表中删除。接下来,创建两个字典,通过标头对它们进行比较,并将它们的内容添加到 StringBuilder,然后从该方法作为单个字符串返回。
本质上,这个方法只做一件事——查找字符串之间的差异。但在内部它执行几个不同的操作,因此我对如何正确格式化这样的方法以及是否有必要尝试这样做感兴趣。在我看来是这样的:
- 方法不应只有一种,而应有多种。第一个是从Main方法中调用的,其他的都是自己调用的;
- 所有函数(创建列表、搜索交集、删除交集、创建字典等)都必须设计为单独的(子)方法,从第一个方法开始按特定顺序调用。因此,第一个方法将仅包含单个操作的列表,并且操作本身将在单独的方法中详细描述。
从字面上看,它看起来不错,但第一个方法需要 4 个参数,调用子方法需要将这些参数传递给每个方法。结果既不短也不清晰......解决方案不是创建单独的方法,而是将它们设计为第一个方法的局部函数 - 然后他们可以使用它的参数。或者将使用的参数放在类字段中。
我还听说过通过对象参数传递多个参数,但我不知道如何正确执行此操作。
这是一个例子。我请有知识的人告诉我如何正确地格式化这个或类似的代码,这样我的头就不会在第一次阅读后开始受伤))提前致谢!
主要方法:
static void Main(string[] args)
{
Console.Write("Введите путь к исходному файлу реестра: ");
string originalRegistry = File.ReadAllText(Console.ReadLine().Replace("\"", ""));
Console.WriteLine();
Console.Write("Введите путь к измененному файлу реестра: ");
string modifiedRegistry = File.ReadAllText(Console.ReadLine().Replace("\"", ""));
Console.WriteLine();
string paragraphSeparator = "[HKEY";
string keyValueSeparator = "\r\n";
File.WriteAllText("RegistryTweaks.reg", FindDifferencesBetweenFiles(originalRegistry, modifiedRegistry, paragraphSeparator, keyValueSeparator));
Console.WriteLine("Готово!");
Console.ReadKey();
}
解析输入文本文件的方法:
static string FindDifferencesBetweenFiles(string originalRegistry, string modifiedRegistry, string paragraphSeparator, string keyValueSeparator)
{
var originalList = originalRegistry.Split(new string[] { paragraphSeparator }, StringSplitOptions.None).ToList();
var modifiedList = modifiedRegistry.Split(new string[] { paragraphSeparator }, StringSplitOptions.None).ToList();
var intersection = originalList.Intersect(modifiedList).ToList();
intersection.ForEach(item => originalList.RemoveAt(originalList.IndexOf(item)));
intersection.ForEach(item => modifiedList.RemoveAt(modifiedList.IndexOf(item)));
var originalDictionary = originalList.ToDictionary(item => paragraphSeparator + item.Substring(0, item.IndexOf(keyValueSeparator)), item => paragraphSeparator + item);
var modifiedDictionary = modifiedList.ToDictionary(item => paragraphSeparator + item.Substring(0, item.IndexOf(keyValueSeparator)), item => paragraphSeparator + item);
var builder = new StringBuilder("Windows Registry Editor Version 5.00\r\n\r\n");
modifiedDictionary.Values.ToList().ForEach(item => builder.Append(item));
foreach (string originalDictionaryKey in originalDictionary.Keys)
{
if (!modifiedDictionary.ContainsKey(originalDictionaryKey))
{
builder.Append(originalDictionary[originalDictionaryKey].Insert(1, "-"));
}
}
return builder.ToString();
}
该程序使用的数据示例:
[HKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\System Resources]
[HKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\System Resources\Loader Reserved]
".Raw"=hex(8):01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,0b,00,00,00,03,\
0e,00,00,00,00,00,00,00,02,00,00,00,00,00,03,01,00,00,00,20,10,00,00,00,00,\
00,00,70,09,00,00,00,00,0064,03,01,00,00,00,00,d0,09,00,00,00,00,00,00,30,00,\
[HKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\System Resources\Physical Memory]
".Translated"=hex(8):01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,09,00,00,\
00,03,01,00,00,00,10,00,00,00,00,00,00,00,c0,09,00,00,00,00,00,03,01,00,00,\
00,00,10,00,00,00,00,00,00,24640,00,00,00,00,00,00,03,01,00,00,00,30,10,00,00,\
00,50,c8,db,00,00,00,00,00,10,18,00,00,00,00,00,03,01,00,00,00,e0,d7,dc,00,\
00,00,00,00,20,28,02,00,00,00,00,07,01,00,02,00,00,00,00,01,00,00,00,00,38,\
1f,03,00,00,00,00
[HKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\System Resources\Reserved]
".Translated"=hex(8):01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,00,00,\
00,03,01,00,00,00,10,00,00,00,00,00,00,00,c0,09,00,00,00,00,00,03,01,00,00,\
00,30,10,00,00,00,00,00,00,60,09,00,00,00,00,00
如果修改后的注册表文件中缺少该键(以“[HKEY”开头且连字符“\r\n”之前的行),则必须通过添加“-”将该键及其内容添加到最终文件中(“[-HKEY”);
如果密钥及其内容*出现在两个分析的文件中且没有更改,则它会被忽略(它不应该出现在输出文件中);
如果该密钥存在于两个分析的文件中,但内容不同,则该密钥必须与修改后的注册表快照中的内容一起放置在最终文件中。
这是一个简单的解释。
该方法有什么作用?
这可以归入数据处理的一个一般阶段;这里没有必要从逻辑上分解该方法。
根据处理的阶段 - 2 个阶段:解析和汇编。但如果其他地方需要这些阶段之间的中间数据,那么将其拆分是有意义的。
总的来说,我建议保持原样。
由于我写了答案,这里是该方法的稍微加速的版本
如果从系统注册表数据结构的处理出发,那么我会基于某种SQLite数据库来完整模拟注册表数据库,这并不是什么天大的困难。它可以处理完全详细的数据,而不是字符串。
只能说您的实现非常粗糙且针对性狭窄。我知道这样做主要是为了性能,但这里的问题是您将如何开发应用程序。一般来说,您可以直接使用注册表开始工作,这可能会更快。