几个星期前我写了这些辅助函数,我觉得我没有利用一些C#语言功能,这些功能会让我不再为其他类似的帮助者编写这些相同的循环。
任何人都可以建议我缺少什么吗?
public static IList<string> GetListOfLinesThatContainTextFromList(
Stream aTextStream, IList<string> aListOfStringsToFind)
{
IList<string> aList = new List<string>();
using (var aReader = new StreamReader(aTextStream))
{
while (!aReader.EndOfStream)
{
var currLine = aReader.ReadLine();
foreach (var aToken in aListOfStringsToFind)
if (currLine.Contains(aToken))
aList.Add(currLine);
}
}
return aList;
}
public static DataTable GetDataTableFromDelimitedTextFile(
Stream aTextStream, string aDelimiter)
{
var aTable = new DataTable();
Regex aRegEx = new Regex(aDelimiter);
using (var aReader = new StreamReader(aTextStream))
{
while (!aReader.EndOfStream)
{
// -snip-
// build a DataTable based on the textstream infos
}
}
return aTable;
}
答案 0 :(得分:6)
我在这里使用作文。例如,对于第一个,首先将位读取线分开 - 并使其变得懒惰......
public static IEnumerable<string> ReadLines(Stream input)
{
// Note: don't close the StreamReader - we don't own the stream!
StreamReader reader = new StreamReader(input);
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
(您可以在MiscUtil中找到功能更全面的版本。)
现在你可以使用LINQ来过滤不在合适的集合中的行(我将使用HashSet
而不是列表,除非它是一个非常短的列表):
var acceptedLines = new HashSet<string>();
// Populate acceptedLines here
var query = ReadLines(input).Where(line => acceptedLines.Contains(line))
.ToList();
填充DataTable时,可以使用相同的行读取方法。你需要小心 - 这是懒惰评估所以你需要保持流打开直到你完成阅读,然后自己关闭它。我更喜欢传递一些东西,让你得到 Stream
(或TextReader
),然后结束逻辑可以在ReadLines
方法中。< / p>
答案 1 :(得分:1)
不幸的是,在这种情况下,我不确定重构在逻辑方面是否值得“节省”。您可以重构这一点,以便将您的using语句和while循环移动到一个单独的方法中,该方法使用Action<T>
委托。这可以作为lambda表达式传递。这与List<T>.ForEach
非常相似。
但是,我认为,在这种情况下,它会使您的代码不易维护。 using语句+ while循环虽然是重复的,但却是一个非常少量的共享代码。 lambda的复杂性可能不值得单个重复的循环结构。
如果涉及更多的共享逻辑,重构这可能是有意义的 - 但除了一个while循环(循环的内部不同),我认为你通过重构使它更复杂。如果您的某个案例需要以不同方式突破,这将特别重要 - 重构这可能会让您的生活更加复杂。
答案 2 :(得分:0)
我同意里德的观点,重构一点点代码可能不值得。但是,你似乎暗示这些代码将存在于几个地方。
我的开发方法是让应用程序正常运行。一旦它工作,通过单元测试,然后我将返回并重构。编码时的重构会冒更难维护代码的风险,因为你增加了一些复杂性,而且任何更多的重构都会继续增加更多。
但是,我已经使用Action委托来传递函数,进行重构,删除重复的代码,但是你的两个例子是完全不同的,因此使用Action委托不会获得任何东西。
如果你可以重做这些函数,那么唯一的区别就是循环中的处理,那么尝试使用Action委托可能是有意义的,但是,如果你想使用LINQ,那么我强烈要求Jon的建议(我当我打字回复时,当别人回应时,我喜欢它。)。