代码之家  ›  专栏  ›  技术社区  ›  The Chairman

为什么内联方法不等于显式声明它?

  •  3
  • The Chairman  · 技术社区  · 15 年前

    你在编程上有盲点吗?

    我的意思是有没有一种你不能真正习惯的常用技巧或语言特征? 嗯,我有一个(或者可能不止一个),我的是 delegate . 举起手来!还有谁对代表不满意?老实点!

    那么代表是什么呢?

    因为我在大学的课程介绍了我C,我知道函数指针。 如果要将方法作为参数传递,函数指针很方便。 所以在我看来,委托就像一个函数指针。尤里卡!我得到了它。我没有!

    一个具体的场景?

    我想删除文本文件中与 regular expression . 假设我有一组线条, List<T> 有方法 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;
    }
    

    所以我在找一个函数 DoesLineMatch 它计算一条线是否匹配一个模式。

    你看到问题了吗?

    移除所有 需要委托 Predicate<string> match 作为论据。 我会这样编码:

    private static bool DoesLineMatch(string line, string pattern)
    {
      return Regex.IsMatch(line, pattern);
    }
    

    但是我得到了一个错误“需要一个带有‘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;
    }
    

    我很高兴它能起作用,但我不明白。

    问题是什么?

    我所做的就是简单地将方法嵌入其中。 据我所知,内联只是一次使用并销毁代码。 如果只使用一次变量或方法,则可以将其内联,但内联始终等同于显式声明它。

    是否有方法显式声明该方法?我该怎么做?

    附:对不起,我的问题有点冗长。

    附言:一旦我得到这个代表的东西,我将从2.0跃升到3.0,并学习lambdas。

    购买力平价:以下 Jon's hint 论效率 Regex.IsMatch(string, string) 我修改了我的代码:

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

    在效率问题上,这没什么帮助。所以我跟着 ReSharper 的建议并将regex实例移动到外部作用域:

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

    现在Resharper敦促我用一个方法组替换它:

      Regex regex = new Regex(pattern);
      int result = lines.RemoveAll(regex.IsMatch);
    

    这与这里提出的答案非常相似。不是我要求的,但我再次惊讶于Resharper(当然还有堆栈溢出)是如何帮助学习的。

    7 回复  |  直到 15 年前
        1
  •  8
  •   Jon Skeet    15 年前

    bool DoesLineMatch(string line, string pattern)
    

    bool Predicate(string value)
    

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

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

    pattern

    Regex.Match(string, string) Regex

        2
  •  2
  •   elder_george    15 年前

    class Matcher {
        public string Pattern;
        bool IsMatch(string value){
           return Regex.IsMatch(Pattern, value);
        }
    }
    

    public static int RemoveLinesFromFile(string path, string pattern)
    {
      List<string> lines = new List<string>(File.ReadAllLines(path));
      Matcher matcher = new Matcher(pattern);
      int result = lines.RemoveAll(matcher.IsMatch);
      File.WriteAllLines(path, lines.ToArray());
      return result;
    }
    

        3
  •  2
  •   Lasse V. Karlsen    15 年前

    public static class DelegateUtils
    {
        public static Predicate<T> ToPredicate<T>(this Func<T, Boolean> func)
        {
            return value => func(value);
        }
    
        public static Func<TResult> Curry<T1, TResult>(
            this Func<T1, TResult> func, T1 firstValue)
        {
            return () => func(firstValue);
        }
    
        public static Func<T2, TResult> Curry<T1, T2, TResult>(
            this Func<T1, T2, TResult> func, T1 firstValue)
        {
            return p2 => func(firstValue, p2);
        }
    
        public static Func<T2, T3, TResult> Curry<T1, T2, T3, TResult>(
            this Func<T1, T2, T3, TResult> func, T1 firstValue)
        {
            return (p2, p3) => func(firstValue, p2, p3);
        }
    
        // if you need more, follow the examples
    }
    

    private static bool DoesLineMatch(string pattern, string line)
    {
        return Regex.IsMatch(line, pattern);
    }
    

    Func<String, String, Boolean> func = DoesLineMatch;
    Func<String, Boolean> predicateCandidate = func.Curry("yourPattern");
    Predicate<String> predicate = predicateCandidate.ToPredicate();
    lines.RemoveAll(predicate);
    

    lines.RemoveAll(new Func<String, String, Boolean>(DoesLineMatch)
        .Curry("yourPattern")
        .ToPredicate());
    
        4
  •  1
  •   Pop Catalin    15 年前

            int result = lines.RemoveAll( delegate (string s) {return DoesLineMatch(s, pattern);});
    
        5
  •  1
  •   reinierpost    15 年前

        6
  •  0
  •   Drew Noakes    15 年前

    pattern

    int result = lines.RemoveAll(l => DoesLineMatch(l, pattern));
    
        7
  •  0
  •   Philippe    15 年前

    bool DoesLineMatch(string line)
    {
      return Regex.IsMatch(line, pattern);
    }