繁体   English   中英

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

[英]C# Noob - Passing a condition as a parameter

我已经有解决此问题的方法,但对我来说似乎混乱且不切实际。

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

这是我理想的状态:

 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。

如果您知道函数将具有的参数,则可以使用Func传递一个函数,该函数将返回布尔值

您的方法定义将如下所示

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

如果行将是这样

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。请参见此方法。 如何在.NET Framework 2.0中模拟“ Func <(Of <(TResult>)>)委托”? 使用代理C#替换Func

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

无论如何,我认为这是使用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;
    }

    }
} 

最后要注意的是,如果您将委托作为条件而不是另一个答案中建议的类实例,则将更健壮。

@Gonzalo。-感谢您的回答,我设法在少数情况下使用了它。 但是现在当我尝试在Func委托中使用更多参数来执行此操作时出现问题,例如,当尝试检查行是否匹配某个Regex模式时:

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;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM