我刚刚安装了 VS2008,遇到了一个问题,我确信可以使用 lambda 或委托(delegate)(或组合!)来解决。
private string ReadData(TcpClient s, string terminator)
{
// Reads a byte steam into a string builder until either data is unavailable or the terminator has not been reached
var sb = new StringBuilder();
do
{
var numBytesRead = s.GetStream().Read(byteBuff, 0, byteBuff.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(byteBuff, 0, numBytesRead));
} while (s.GetStream().DataAvailable && !sb.ToString().Contains(terminator));
return sb.ToString();
}
问题是,有时我需要检查字符串是否包含两个不同值中的任何一个。有时我可能需要检查它的三个值。
所以我的建议是将“!sb.ToString().Contains(terminator)”更改为传递到方法中的函数。
我可以编写不同的函数,例如:
private bool compare1(string s, string t) {
return s.contains(t)
}
private bool compare2(string s, string t1, string t2) {
return (s.compare(t1) or s.compare(t2)
}
// etc...
然后,当我想与 3 个不同的值进行比较时,为这些函数之一创建一个委托(delegate),然后将其传递给 ReadData() 方法。
对于委托(delegate),我一无所知,我不确定这是否适合放置 lambda,但有些东西告诉我它是。
调用代码是这样的:
// Enter username .
if (HasData(s,"login:"))
SendData(s, switchUser + TelnetHelper.CRLF);
HasData 与 ReadData 相同,但返回的是 bool 值而不是字符串(我也想使用一些技巧将其分解为一个方法 - 但这是一个次要问题 - 不过请随时回答。
仅供引用:
private bool HasData(TcpClient s, string terminator)
{
// Reads a byte steam into a string builder until either data is unavailable or the terminator has not been reached
var sb = new StringBuilder();
do
{
var numBytesRead = s.GetStream().Read(byteBuff, 0, byteBuff.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(byteBuff, 0, numBytesRead));
} while (s.GetStream().DataAvailable && !sb.ToString().Contains(terminator));
return sb.ToString().Contains(terminator);
}
最佳答案
听起来您正在寻找谓词函数。不要对检查进行硬编码,而是将委托(delegate)作为参数来进行检查
private string ReadData(TcpClient s, Func<string,bool> predicate)
{
// Reads a byte steam into a string builder until either data is unavailable or the terminator has not been reached
var sb = new StringBuilder();
do
{
var numBytesRead = s.GetStream().Read(byteBuff, 0, byteBuff.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(byteBuff, 0, numBytesRead));
} while (s.GetStream().DataAvailable && !predicate(sb));
return sb.ToString();
}
然后你可以创建几个包装器,这些包装器只创建适当的委托(delegate)并将其传递下去
public bool HasData(TcpClient c, string terminator) {
return HasData(c, (s) => s.Contains(terminator));
}
public bool HasData(TcpClient c, string t1, string t2) {
return HasData(c, (s) => s.Contains(t1) || s.Contains(t2));
}
您甚至可以根据任意数量的终止符即时构建委托(delegate)
public bool HasData(TcpClient c, params string[] terminatorList) {
return HasData(c, (s) => terminatorList.Where(x => s.Contains(x)).Any());
}
关于c# - 使用 Lambda 和委托(delegate)进行重构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/809945/