【问题标题】:How do i execute anonymous function in another function's parameters to fill one of its parameters?如何在另一个函数的参数中执行匿名函数来填充它的一个参数?
【发布时间】:2018-09-19 16:29:33
【问题描述】:

所以我有这个 C# 代码:

static void Main(string[] args)
{            
   string @string = "- hello dude! - oh hell yeah hey what's up guy";

   Console.WriteLine(String.Join(".", @string.GetSubstringsIndexes("he")));
   Console.Read();
}

添加扩展“GetSubstringsIndexes”方法的部分类:

partial class StringExtension
{
    public static int[] GetSubstringsIndexes(this string @string, string substring)
    {
        List<int> indexes = new List<int>(@string.Length / substring.Length);

        int result = @string.IndexOf(substring, 0);
        while (result >= 0)
        {
            indexes.Add(result);
            result = @string.IndexOf(substring, result + substring.Length);
        }

        return indexes.ToArray();
    }
}

我希望它是一个在 String.Join 方法的参数括号中的 lambda 表达式,而不是调用我编写的函数。

我的意思是,我不想写这个函数然后调用它,而是写一个 lambda 表达式只使用一次!

我希望它看起来如何的示例:

static void Main(string[] args)
{            
   string @string = "- hello dude! - oh hell yeah hey what's up guy";

   Console.WriteLine(String.Join(".", () => {List<int> ind = new List<int>()..... AND SO ON...} ));
   Console.Read();
}

嗯,实际上,我刚刚意识到(在写这个问题时)对于这种情况是不必要的,因为我的 GetSubStringsIndexes 方法太大了。但想象一下,如果它很短。

请告诉我是否可以做这样的事情,如果可以,请告诉我如何做!

编辑:

我已经完成了,看起来就是这样:

        Console.WriteLine(String.Join(".", ((Func<int[]>)
            ( () => 
            {
                List<int> indx = new List<int>();
                int res = @string.IndexOf("he", 0);
                while (res >= 0)
                {
                    indx.Add(res);
                    res = @string.IndexOf("he", res + "he".Length);
                }
                return indx.ToArray();
            }
            ))()));

【问题讨论】:

  • 您想在此时执行一段代码并将结果传递给 string.join?
  • 是的,这正是我想做的。

标签: c# lambda functional-programming


【解决方案1】:

您在问题中的“改进”有效。这是一种更简洁的方法,使用您只需要定义一次的辅助函数:

static void Execute<TReturn>(Func<TReturn> func) => func();

然后:

Console.WriteLine(Execute(() => { /* any code here */ }));

这会自动推断委托类型并调用委托。这消除了很多混乱。

一般来说,我建议不要使用这种风格。改用多行代码。

【讨论】:

    【解决方案2】:

    你想要什么是不可能的,因为String.join() 不接受Func&lt;int[]&gt;Expression&lt;Func&lt;int[]&gt;&gt;

    如果您不想编写扩展方法,可以使用本地函数并调用它。

    static void Main(string[] args)
    {            
       string @string = "- hello dude! - oh hell yeah hey what's up guy";
    
       Console.WriteLine(String.Join(".", GetIndexes('he'));
       Console.Read();
    
       int[] GetIndexes(string substring) {
           var indexes = new List<int>();
           // compute indexes as desired. @string is available here.
           return indexes.ToArray();
       }
    }
    

    【讨论】:

    • 请记住,本地函数仅在 C# 7 中可用
    • 另外,这不是 lambda 表达式(作为 OP 请求)
    • 好吧,除了 lambda 表达式,我也会接受匿名方法。是的,我可以这样写是可以理解的。但我只是喜欢用“1-line”风格写作
    • 其实是可以的,看我对问题的改进。
    【解决方案3】:

    一种方法是使用Select 语句,在该语句中捕获正在检查的字符及其在字符串中的索引(使用语法:Select((item, index) =&gt; ...),然后,如果子字符串存在于那个位置index,返回索引,否则返回-1(来自Select 语句),然后使用Where 子句删除任何-1 结果。

    代码有点长,因为我们还必须确保在检查子字符串之前我们不会太靠近字符串的末尾(这会导致另一个返回 -1 的三元条件)。

    我确信这可以改进,但这是一个开始:

    string @string = "- hello dude! - oh hell yeah hey what's up guy";           
    
    var subString = "he";
    
    Console.WriteLine(string.Join(".", @string.Select((chr, index) =>
        index + subString.Length < @string.Length
            ? @string.Substring(index, subString.Length) == subString
                ? index
                : -1
            : -1)
        .Where(result => result > -1)));
    

    如果太难阅读(由于多个?: 三元表达式),这里是每行前的 cmets:

    // For each character in the string, grab the character and it's index
    Console.WriteLine(string.Join(".", @string.Select((chr, index) =>
        // If we're not too close to the end of the string
        index + subString.Length < @string.Length
            // And the substring exists at this index          
            ? @string.Substring(index, subString.Length) == subString
                // Return this index
                ? index
                // Substring not found here; return -1
                : -1
            // We're too close to end; return -1
            : -1) 
        // Return only the indexes where the substring was found
        .Where(result => result > -1)));
    

    【讨论】:

      【解决方案4】:

      最终结果:

      Console.WriteLine(String.Join(".", ((Func<int[]>)
          ( () => 
          {
              List<int> indx = new List<int>();
              int res = @string.IndexOf("he", 0);
              while (res >= 0)
              {
                  indx.Add(res);
                  res = @string.IndexOf("he", res + "he".Length);
              }
              return indx.ToArray();
          }
      ))()));
      

      【讨论】:

        猜你喜欢
        • 2022-11-10
        • 1970-01-01
        • 2018-07-30
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        • 1970-01-01
        • 2023-03-22
        相关资源
        最近更新 更多