为什么不内联一个等效于明确声明它的方法?

The*_*man 3 c# delegates inline c#-2.0

编程中你有盲点吗?

我的意思是有一种常见的技术或语言功能,你不能真正习惯.好吧,我有一个(或者可能不止一个),我的用法是delegate.举手!还有谁对代表感到不舒服?说实话!

那么什么是代表?

由于我在大学的课程向我介绍了C,我知道函数指针.如果要将方法作为参数传递,函数指针很方便.所以在我看来,委托就像一个函数指针.找到了!我知道了.我还没有!

一个具体的场景?

我想从文本文件中删除与正则表达式匹配的任何行.假设我有一系列线条,那么这种List<T>方法RemoveAll似乎非常适合这个目的. RemoveAll期望将评估方法作为决定是否删除或保留列表元素的参数.它是:函数指针!

这里有代码吗?

public static int RemoveLinesFromFile(string path, string pattern)
{
  List<string> lines = new List<string>(File.ReadAllLines(path));
  int result = lines.RemoveAll(DoesLineMatch);
  File.WriteAllLines(path, lines.ToArray());
  return result;
}
Run Code Online (Sandbox Code Playgroud)

所以我正在寻找一个函数DoesLineMatch来评估一条线是否与一个模式相匹配.

你看到了问题吗?

RemoveAll期望代表Predicate<string> match作为参数.我会像这样编码:

private static bool DoesLineMatch(string line, string pattern)
{
  return Regex.IsMatch(line, pattern);
}
Run Code Online (Sandbox Code Playgroud)

但后来我收到一个错误"预期带有'bool DoesLineMatch(string)'签名的方法".我在这里错过了什么?

它有用吗?

这就是我最终使它工作的方式:

public static int RemoveLinesFromFile(string path, string pattern)
{
  List<string> lines = new List<string>(File.ReadAllLines(path));
  int result = lines.RemoveAll(delegate(string line)
    {
      return Regex.IsMatch(line, pattern);
    });
  File.WriteAllLines(path, lines.ToArray());
  return result;
}
Run Code Online (Sandbox Code Playgroud)

我很高兴它有效,但我不明白.

问题是什么?

我所做的工作就是简单介绍方法.据我所知,它只是某种使用 - 一次和破坏 - 代码.如果您只使用变量或方法一次内联它,但内联总是等同于明确声明它.

有没有办法明确声明方法?我该怎么办?

PS:请原谅我,我的问题有点冗长.

PPS:一旦我得到这个委托的东西,我将从2.0跳到3.0并学习lambdas.

PPPS:继JonRegex.IsMatch(string, string)我修改代码的效率提示之后:

  int result = lines.RemoveAll(delegate(string line)
    {
      Regex regex = new Regex(pattern);
      return regex.IsMatch(line);
    });
Run Code Online (Sandbox Code Playgroud)

这对效率问题没有多大帮助.所以我遵循了ReSharper的提议并将Regex实例化移到了外部范围:

  Regex regex = new Regex(pattern);
  int result = lines.RemoveAll(delegate(string line)
    {
      return regex.IsMatch(line);
    });
Run Code Online (Sandbox Code Playgroud)

现在ReSharper敦促我用方法组替换它:

  Regex regex = new Regex(pattern);
  int result = lines.RemoveAll(regex.IsMatch);
Run Code Online (Sandbox Code Playgroud)

这与此处提出的答案非常相似.不是我要求的,但我又惊讶于ReSharper(当然还有Stack Overflow)如何帮助学习.

Jon*_*eet 8

您正在尝试使用具有以下签名的方法:

bool DoesLineMatch(string line, string pattern)
Run Code Online (Sandbox Code Playgroud)

对于有签名的代表:

bool Predicate(string value)
Run Code Online (Sandbox Code Playgroud)

从哪里获得第二个字符串值(模式)?

使用显式声明的方法执行此操作的唯一方法是这样的:

public sealed class RegexHolder
{
    private readonly string pattern;

    public RegexHolder(string pattern)
    {
        this.pattern = pattern;
    }

    public bool DoesLineMatch(string line)
    {
        return Regex.IsMatch(line, pattern);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

public static int RemoveLinesFromFile(string path, string pattern)
{
    List<string> lines = new List<string>(File.ReadAllLines(path));
    RegexHolder holder = new RegexHolder(pattern);
    int result = lines.RemoveAll(holder.DoesLineMatch);
    File.WriteAllLines(path, lines.ToArray());
    return result;
}
Run Code Online (Sandbox Code Playgroud)

这与编译器使用匿名方法为您做的很接近 - 它将创建一个嵌套类来保存捕获的变量(pattern在本例中).

(请注意,我已经避免讨论调用的效率,Regex.Match(string, string)而不是创建一个单独的实例Regex......这是另一回事.)