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:继Jon对Regex.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)如何帮助学习.
您正在尝试使用具有以下签名的方法:
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......这是另一回事.)
| 归档时间: |
|
| 查看次数: |
597 次 |
| 最近记录: |