Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Lambda'进行重构;代表和代表_C#_.net_Refactoring_Delegates_Lambda - Fatal编程技术网

C# 使用Lambda'进行重构;代表和代表

C# 使用Lambda'进行重构;代表和代表,c#,.net,refactoring,delegates,lambda,C#,.net,Refactoring,Delegates,Lambda,我刚刚安装了VS2008,遇到了一个问题,我确信可以通过lambda或委托(或组合!)解决 问题是,有时我需要检查字符串是否包含两个不同的值。有时我可能需要检查它的三个值 因此,我建议将“!sb.ToString().Contains(terminator)”更改为传递到方法中的函数 我可以编写不同的函数,例如: private bool compare1(string s, string t) { return s.contains(t) } private bool compare

我刚刚安装了VS2008,遇到了一个问题,我确信可以通过lambda或委托(或组合!)解决

问题是,有时我需要检查字符串是否包含两个不同的值。有时我可能需要检查它的三个值

因此,我建议将“!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个不同的值时,创建一个对其中一个函数的委托,然后将其传递给ReadData()方法

当谈到代表时,我非常无知,我不确定这是否是一个适合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);
    }

听起来你在寻找一个谓词函数。与其对检查进行硬编码,不如将委托作为一个参数来执行检查

    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();
    }
甚至可以基于任意数量的终止符动态构建委托

public bool HasData(TcpClient c, params string[] terminatorList) {
  return HasData(c, (s) => terminatorList.Where(x => s.Contains(x)).Any());
}

听起来你在寻找一个谓词函数。与其对检查进行硬编码,不如将委托作为一个参数来执行检查

    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();
    }
甚至可以基于任意数量的终止符动态构建委托

public bool HasData(TcpClient c, params string[] terminatorList) {
  return HasData(c, (s) => terminatorList.Where(x => s.Contains(x)).Any());
}

一个选项是重载ReadData()方法以获取包含要检查的值的字符串数组。使用,可以扩展Contains()以获取字符串数组

ReadData()方法可以是:

private string ReadData(TcpClient s, string[] terminators) {
    // 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(terminators));

    return sb.ToString();
}
public static bool Contains ( this String str , String[] testValues )
{
    foreach ( var value in testValues )
    {
        if ( str.Contains( value ) )
            return true;
    }
    return false;
}
Contains()方法扩展可以是:

private string ReadData(TcpClient s, string[] terminators) {
    // 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(terminators));

    return sb.ToString();
}
public static bool Contains ( this String str , String[] testValues )
{
    foreach ( var value in testValues )
    {
        if ( str.Contains( value ) )
            return true;
    }
    return false;
}

此实现消除了每次有不同数量的字符串要测试时创建新谓词的需要。

一个选项是重载ReadData()方法以获取包含要检查的值的字符串数组。使用,可以扩展Contains()以获取字符串数组

ReadData()方法可以是:

private string ReadData(TcpClient s, string[] terminators) {
    // 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(terminators));

    return sb.ToString();
}
public static bool Contains ( this String str , String[] testValues )
{
    foreach ( var value in testValues )
    {
        if ( str.Contains( value ) )
            return true;
    }
    return false;
}
Contains()方法扩展可以是:

private string ReadData(TcpClient s, string[] terminators) {
    // 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(terminators));

    return sb.ToString();
}
public static bool Contains ( this String str , String[] testValues )
{
    foreach ( var value in testValues )
    {
        if ( str.Contains( value ) )
            return true;
    }
    return false;
}

此实现消除了每次需要测试不同数量的字符串时创建新谓词的需要。

因为lambdas的语法对我自己(以及我的团队的其他成员)来说有些陌生,所以我最终使用了一个稍微不同的解决方案。我无法理解.All()的语法从上面的.Any()函数修改时

我还需要一个.All()函数,以确保找到列表中的所有终止符。因此,我最终使用了如下内容:

delegate bool Predicate (string s, params [] string terminators);

bool HasAll(string s, params string [] terminators) {
    foreach (var t in terminators) {
       if (!s.contains(t)) return false;
    }
    return true;
}

bool HasAny(string s, params string [] terminators) {
    foreach (var t in terminators) {
        if (s.contains(t)) return true;
    }
    return false;
}
// Just looking now, I could also pass in a bool to switch between the two and remove one of these functions. But this is fairly clear


string ReadData(TcpClient sock, Function predicate, params [] string terminators) {
    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.ToString(), terminators);

    return sb.ToString();
}
然后调用代码如下所示:

private void someFunc() 
{
    Predicate any = new Predicate(HasAny);
    Predicate all = new Predicate(HasAll);
    String response;

    // Check all strings exist
    response = ReadData(this.sock, all, "(", ")", "->")
    if (all(response, "(", ")", "->")
        SendData(this.sock, ...);

    // Check any string exists
    response = ReadData(this.sock, any, "Hi", "Hey", "Hello");
    if (any(response, "Hi", "Hey", "Hello"))
       SendData(this.sock, ...);
}
我可能会在Has[Any | All]函数中添加null检查,将do..while改为while,然后只检查response!=null,而不是复制参数。我认为这种解决方案适合我的所有用例,并且是相当容易理解的。只要我做了上面提到的小更改


但是,这一切都突出了我学习lambda表达式的必要性!

因为lambda的语法对我自己(和我的团队其他成员)来说有些陌生,所以我最终选择了一个稍微不同的解决方案。当从上面的.Any()函数修改时,我无法理解.All()的语法

我还需要一个.All()函数,以确保找到列表中的所有终止符。因此,我最终使用了如下内容:

delegate bool Predicate (string s, params [] string terminators);

bool HasAll(string s, params string [] terminators) {
    foreach (var t in terminators) {
       if (!s.contains(t)) return false;
    }
    return true;
}

bool HasAny(string s, params string [] terminators) {
    foreach (var t in terminators) {
        if (s.contains(t)) return true;
    }
    return false;
}
// Just looking now, I could also pass in a bool to switch between the two and remove one of these functions. But this is fairly clear


string ReadData(TcpClient sock, Function predicate, params [] string terminators) {
    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.ToString(), terminators);

    return sb.ToString();
}
然后调用代码如下所示:

private void someFunc() 
{
    Predicate any = new Predicate(HasAny);
    Predicate all = new Predicate(HasAll);
    String response;

    // Check all strings exist
    response = ReadData(this.sock, all, "(", ")", "->")
    if (all(response, "(", ")", "->")
        SendData(this.sock, ...);

    // Check any string exists
    response = ReadData(this.sock, any, "Hi", "Hey", "Hello");
    if (any(response, "Hi", "Hey", "Hello"))
       SendData(this.sock, ...);
}
我可能会在Has[Any | All]函数中添加null检查,将do..while改为while,然后只检查response!=null,而不是复制参数。我认为这种解决方案适合我的所有用例,并且是相当容易理解的。只要我做了上面提到的小更改


这件事让我意识到我需要学习lambda表达式!

虽然谓词(sb)需要更改为谓词(sb.ToString())-不允许我编辑。语法让我有些困惑。它不应该在(x=>s.contains(x)).any()的位置,因为s是我们要检查终止符的字符串吗?@Josh,是的,你在哪里写错误。我修正了。虽然谓词(sb)需要更改为谓词(sb.ToString())-但不允许我编辑。语法让我有些困惑。它不应该是(x=>s.contains(x)).any()),因为s是我们要检查终结符的字符串吗?@Josh,是的,你在where中写的bug。我修好了。