如何LINQ验证以下循环



我在C#程序中有一个方法。它枚举某个文件夹中的所有.cs文件,然后在列表中运行。对于每个文件,我使用File.ReadAllLines读取所有行。我只想处理一个文件,如果它包含一个类,无论是传统的static,还是abstract,,其名称以某个短语开头,而不是以单词Tests.结尾。此外,我希望在包含类声明的行中找到行索引,即public static class Foo部分。

假设我获取File.ReadAllLines的结果,并对其调用ToList()以创建List<string>,我希望使用FindIndex方法使用谓词来查找与我的条件匹配的行的索引(如果存在(。

我的问题是:写这样一个谓词的好方法是什么?

我意识到我可能会使用更复杂的方法,但我只是将这些代码放入一个快速而肮脏的LINQPad脚本中。所以,我不必太喜欢。

让我向您展示到目前为止我所拥有的内容(假设最外层的命名空间和类已经被适当地声明(:

void Main()
{
var files = Directory
.EnumerateDirectories(
Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.UserProfile
), @"sourcereposastrohartMFR"
), "*", SearchOption.TopDirectoryOnly
).SelectMany(
x => Directory.EnumerateFiles(
x, "FileSystemEntry*.cs", SearchOption.AllDirectories
)
)
.Where(x => !"FileSystemEntry.cs".Equals(Path.GetFileName(x)))
.ToList();
if (files == null || !files.Any()) return;
foreach (var file in files)
{
var contents = string.Empty;
try
{
contents = File.ReadAllText(file);
}
catch (Exception ex)
{
Console.WriteLine($"ERROR: {ex.Message}");
contents = string.Empty;
}
if (string.IsNullOrWhiteSpace(contents)) continue;
if (contents.Contains("[TestFixture]")) continue;
if (contents.Contains("[Log(AttributeExclude = true)]")) continue;
file.Dump();
var lines = new List<string>();
lines.TrimExcess();
try
{
lines = File.ReadAllLines(file).ToList();
}
catch (Exception ex)
{
Console.WriteLine($"ERROR: {ex.Message}");
lines = new List<string>();
lines.TrimExcess();
}
if (lines == null || !lines.Any()) continue;
var index = -1;
for (var i = 0; i < lines.Count; i++)
{
var currentLine = lines[i].Trim();
if (currentLine.EndsWith("Tests")) continue;
if (currentLine.StartsWith("public static class FileSystemEntry"))
{
index = i;
break;
}
if (currentLine.StartsWith("public class FileSystemEntry"))
{
index = i;
break;
}
if (currentLine.StartsWith("public abstract class FileSystemEntry"))
{
index = i;
break;
}
}
if (index < 0) continue;

/*...*/
}
}

如何在中翻译for循环

var index = -1;
for (var i = 0; i < lines.Count; i++)
{
var currentLine = lines[i].Trim();
if (currentLine.EndsWith("Tests")) continue;
if (currentLine.StartsWith("public static class FileSystemEntry"))
{
index = i;
break;
}
if (currentLine.StartsWith("public class FileSystemEntry"))
{
index = i;
break;
}
if (currentLine.StartsWith("public abstract class FileSystemEntry"))
{
index = i;
break;
}
}
if (index < 0) continue;

因此:

var index = lines.FindIndex(currentLine => /*...*/);

我需要帮助了解如何派生与for循环相匹配的lambda表达式的正确主体。

提前感谢!

编辑1

我眯着眼睛看了看我的眼窝。我正在寻找一个谓词,专门用于FindIndex方法。我想了想,我想也许我可以逃脱:

var index = lines.FindIndex(currentLine => !currentLine.Trim.EndsWith("Tests") && currentLine.Trim().StartsWith("public static class FileSystemEntry") || currentLine.Trim().StartsWith("public class FileSystemEntry") || currentLine.Trim().StartsWith("public abstract class FileSystemEntry"));

也许我可以实现一个扩展方法

public static bool StartsWithAnyOf(this string value, params string[] testStrings)
{
var result = false;
try
{
if (string.IsNullOrWhiteSpace(value.Trim())) return result;
if (testStrings == null || !testStrings.Any()) return result;
foreach(var element in testStrings)
if (value.Trim().StartsWith(element))
{
result = true;
break;
}
}
catch
{
result = false;
}
return result;
}

然后我会声明另一种方法:

public static bool KeepLine(string currentLine)
{
if (string.IsNullOrWhiteSpace(currentLine.Trim())) return false;
if (currentLine.Trim().EndsWith("Tests")) return false;

return currentLine.StartsWithAnyOf(
"public static class FileSystemEntry",
"public class FileSystemEntry",
"public abstract FileSystemEntry"
);
}

然后这样使用:

var index = lines.FindIndex(KeepLine);

这样行吗?

我还没有对此进行彻底的测试,但与上面提供的原始代码相比,它似乎通过了基本的健全性。请注意,在衡量性能时,这并不是最好的。带有匿名函数的"foreach"循环存在无法脱离匿名函数的缺陷。实现foreach的唯一方法是运行所有foreach语句。为了保留条件与行内容匹配的第一个索引,我在else-if((比较语句中使用了索引。这意味着foreach循环将为所有行运行,尽管找到了第一个匹配行。

lines.ForEach((l) =>
{
if (l.EndsWith("Tests")) ;
else if (index ==0 && (l.StartsWith("public static class FileSystemEntry") ||
l.StartsWith("public class FileSystemEntry") ||
l.StartsWith("public abstract class FileSystemEntry")))
{
index = lines.IndexOf(l);
}
});

相关内容

  • 没有找到相关文章

最新更新