C#Noob - 将条件作为参数传递

时间:2017-03-02 02:09:54

标签: c# .net .net-2.0

我已经有了这个问题的解决方案,但似乎非常让我感到困惑和不切实际。

我打算做的是逐行读取文件(由于文件大小,一次性将其加载到内存中是不切实际的),并且如果满足某些条件(例如:该行匹配正则表达式模式,或包含某些关键字,或等于某个字符串)

这是我理想的选择:

 void TryGetLineIf(string filePath, Condition condition, out string desiredLine)
  {
     StreamReader fileReader = new StreamReader(filePath);
     string currentLine = "";

     while (!fileReader.EndOfStream)
     {
        currentLine = fileReader.ReadLine();

        if (condition)
        {
           desiredLine = currentLine;
        }
     }
  }

但是,我不知道如何处理condition参数。我能想到的唯一出路是用枚举替换条件,(LineSelectionOptions.IsRegexMatch,LineSelectionOptions.ContainsString ...),向void添加一个额外的参数,并在它之间切换可能的值。我正在使用.NET 2.0,如果这是相关的。

3 个答案:

答案 0 :(得分:3)

如果您知道函数的参数,可以使用Func传递一个返回bool的函数

你的方法定义将是这样的

 void TryGetLineIf(string filePath, Func<string, bool> condition, out string desiredLine)

if-line将是这样的

if(condition(currentLine)) {
   desiredLine = currentLine;
}

并且对方法的调用将是这样的

Func<string, bool> condition = (line) => line.Length > 1;
string desiredLine;
TryGetLineIf("C:\\....file.pdf", condition, out desiredLine)

但是,由于您在2.0中工作,您可能希望使用委托来模拟Func 请参阅此How to simulate a "Func<(Of <(TResult>)>) Delegate" in .NET Framework 2.0?或此Replacing Func with delegates C#

答案 1 :(得分:0)

请原谅格式,因为我在手机上。

无论如何,我认为这是使用yield return的完美候选者,因为调用者可以决定break而不想在任何行之后读取文件的其余部分。这样就可以了。此外,呼叫者可以执行链接并进行进一步处理。此外,不需要out参数。

确保使用using语句,如果在.NET 2.0中可用,请使用File.ReadLines方法:它逐行读取,它更简单。一旦我回到家,我会尝试用我提出的建议来编辑我的答案。

public static IEnumerable<string> TryGetLineIf(string filePath, Condition condition
{
     StreamReader fileReader = new StreamReader(filePath);
     string currentLine = "";

 while (!fileReader.EndOfStream)
 {
    currentLine = fileReader.ReadLine();

    if (condition.MeetsCriteria(currentLine))
    {
         yield  return currentLine;
    }

    }
} 

作为最后一点,如果您将委托作为条件而不是另一个答案中建议的类实例传递,则它会更强大。

答案 2 :(得分:0)

@ Gonzalo.-感谢您的回答,我设法在少数情况下使用它。但是现在我在尝试使用Func委托中的更多参数时遇到问题,例如,当尝试检查该行是否与某个正则表达式模式匹配时:

Func<string, string, bool> condition = 
(line, pattern) => new Regex(pattern).IsMatch(line)

IEnumerable<string> LinesIWant =
ReturnLineIf("C:\test.txt", condition);

以下是方法:

IEnumerable<string> ReturnLineIf(string filePath, Func<string, string, bool> condition)
{
  // (snip)
  // How do I specify a pattern when calling the method?
  if (condition(currentLine, "This should be the pattern..."))
  {
    yield return currentLine;
  }
}