Func和Action委托的区别和简单使用

本文详细对比了C#中Func和Action委托的区别,并提供了使用实例。此外,还深入介绍了正则表达式的多种应用场景及其高级用法。

前言:下面几条都是根据自己开发经验和网上资料整理总结的,初学者可适当入门学习,加深印象,高手请54.
Func和Action委托的区别和简单使用
1、两种委托的常见形式和区别
(1)、Func委托有5个重载形式,区别仅在于它所指向的方法的签名的参数个数,分别如下:

Func<TResult>

Func<T,TResult>

Func<T1,T2,TResult>

unc<T1,T2,T3,TResult>

Func<T1,T2,T3,T4,TResult>
其中T,T1,..T4是委托指向的方法的参数的类型,TResult为方法的返回类型。
(2)、Action委托也有5个重载形式,分别如下:
Action

Action<T>

Action<T1,T2>

Action<T1,T2,T3>

Action<T1,T2,T3,T4>
其中T,T1,..T4是委托指向的方法的参数的类型。
从上面的委托形式我们就可以分析出来,Func和Action委托的唯一区别在于Func要有返回值Action没有返回值。
2、简单示例代码

ExpandedBlockStart.gif 代码
   class  Program
    {
        
static   void  Main( string [] args)
        {
            
int  num  =   5 ;
            
/*   Func和Action委托的唯一区别在于Func要有返回值, Action没有返回值  */
            FirstCalcSquare calFirst 
=  Square; // delegate
            Console.WriteLine( " The square of {0} is {1}. " , num, calFirst(num));

            Func
< int int >  funcTest  =  Program.Square; // Func
            Console.WriteLine( " The square of {0} is {1}. " , num, funcTest(num));

            SecondCalcSquare calSecond 
=  GetSquere;
            calSecond(num);
// delegate

            Action
< int >  actionTest  =  Program.GetSquere;
            actionTest(num);
// Action

            Console.ReadLine();
        }
        
private   delegate   int  FirstCalcSquare( int  input);
        
private   static   int  Square( int  input)
        {
            
return  input  *  input;
        }

        
private   delegate   void  SecondCalcSquare( int  input);
        
private   static   void  GetSquere( int  input)
        {
            Console.WriteLine(
" The square of {0} is {1}. " , input, input  *  input);
        }

    }

 
附1:通过命令行保存webservice为本地的类
经常用到这个功能,通过如下的vs命令行:
wsdl  http://www.xxx.com/TesterWebService.asmx  /l:cs  /n:Test
说明:wsdl url   /l:cs(指定语言)  /n:(命名空间)

附2:c#正则表达式使用小结
一、正则表达式概述
1、正则表达式可以看作是一种有特定功能的小型编程语言:在大的字符串表达式中定位一个子字符串。它不是一种新技术,最初是在unix环境中开发的,与perl一起使用的较多。ms把它移植到windows中,System.Text.RegularExpression命名空间中的许多.net类都支持正则表达式。
2、主要包含的两个功能
(1)一组用于标识字符类型的转义字符。您可能熟悉dos表达式中的*字符表示任意字符串(例如,dos命令dir pro*会列出所有名称以pro开头的文件)。
(2)一个系统。在搜索操作中,它把字符串和中间结果的各个部分组合起来。
二、示例
1、常见的特定字符或转义序列

符号        含义        示例              匹配的示例
^     输入文本的开头    ^a       a,但只能是文本的第一个字符
$     输入文本的结尾    z$         z,但只能是文本的最后一个字符
.     除了换行符(\n)  a.c        abc,azc,
       外所有单个字符
*     >=0次的前导字符   ab*c     ac,abc,abbc,
+     >=1次的前导字符   ab+c     abc,abbc,abbbc,
?     可以重复0次或1次  ab?c       ac或者abc
       的前导字符   
\s    任意空白字符      \sa      [space]a,\ta,\na
\S    \s的补集          \Sa      aa,ba不能是\ta,\na等
\d    0-9的数字         \da      1a,2a,9a
\D    \d的补集          \Da       aa,+a..不会是数字和a的组合
\b    字边界             abc\b   以abc结尾的任何文本
\B    不是字边界的位置   \Babc\B  字中间的任何abc

\w    单词字符,指大小写字母、0-9的数字、下划线
\W    \w的补集

简单示例代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//1.^和$
            string strSource = "think in c# deeply";
            Regex myReg 
= new Regex("think in c# deeply");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            myReg = new Regex("^think in c# deeply$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            myReg = new Regex("^think in c# deep$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            myReg = new Regex("^Think in c# deeply$");
            Console.WriteLine(myReg.IsMatch(strSource));
//false

            
//带换行的情况
            strSource = @"think in 
c# deeply
";
            myReg 
= new Regex("think in \r\nc# deeply");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            myReg = new Regex("^think in \r\nc# deeply$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            myReg = new Regex("^think in c# deeply$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            myReg = new Regex("^think in c# deeply$");
            Console.WriteLine(myReg.IsMatch(strSource));
//false

            
//2..,*,+,?
            strSource = "abc xybzac acbab";
            myReg 
= new Regex(".b");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//4处匹配
            strSource = "abcdefg asdfghjkbedk aabccd";
            myReg 
= new Regex("a*b");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//3处匹配
            myReg = new Regex("a+b");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//2处匹配
            myReg = new Regex("a?b");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//3处匹配

            
//3.\s和\S
            strSource = "aoe iuv abc uvaw abcxyz";
            myReg 
= new Regex(@"\sa");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//2处匹配
            myReg = new Regex(@"\Sa");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//1处匹配

            
//4.\d和\D
            strSource = "123aoe iuv abc uv789aw abcxyz";
            myReg 
= new Regex(@"\da");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//2处匹配
            myReg = new Regex(@"\Da");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//2处匹配

            
//5.\b和\B
            strSource = "aoe iuv abc uv789aw abcxyz";
            myReg 
= new Regex(@"\ba");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//3处匹配
            myReg = new Regex(@"\Ba");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//1处匹配
            myReg = new Regex(@"\Ba\B");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//1处匹配

            
//6.\w和\W
            strSource = "abc123_()*&$";
            myReg 
= new Regex(@"\w");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//7处匹配
            myReg = new Regex(@"\W");
            Console.WriteLine(myReg.Matches(strSource).Count); 
//5处匹配

            Console.ReadLine();
        }
    }
}

2、特殊字符的匹配

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//1.\,双引号",和星号*
            string strSource = "\\\\";
            Regex myReg 
= new Regex(@"^\\\\$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1
            strSource = @"\\";
            myReg 
= new Regex(@"^\\\\$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            strSource 
= "\"";
            myReg = new Regex(@"^""$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            strSource 
= "\"\"";
            myReg 
= new Regex(@"^""""$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            strSource 
= "*";
            myReg 
= new Regex(@"^\*\*$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            Console.WriteLine(myReg.Matches(strSource).Count); //0

            strSource 
= "**";
            myReg 
= new Regex(@"^\*\*$");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            Console.ReadLine();
        }
    }
}

3、常见重复描述字符
{n}  匹配前面的字符n次
{n,}  匹配前面的字符n次或多于n次
{n,m}  匹配前面的字符n到m次
示例:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//1.{n},{n,}和{n,m} 
            string strSource = "abc123xyz";
            Regex myReg 
= new Regex(@"\d{3}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            myReg 
= new Regex(@"\w{9}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            myReg 
= new Regex(@"\w{10}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            Console.WriteLine(myReg.Matches(strSource).Count); //0

            myReg 
= new Regex(@"\d{1,}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            myReg 
= new Regex(@"\d{3,}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //1

            myReg 
= new Regex(@"\d{4,}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            Console.WriteLine(myReg.Matches(strSource).Count); //0

            myReg 
= new Regex(@"\D{1,3}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //2

            myReg 
= new Regex(@"\D{2,3}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //2

            myReg 
= new Regex(@"\D{4,5}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            Console.WriteLine(myReg.Matches(strSource).Count); //0

            Console.ReadLine();
        }
    }
}

4、表示匹配“或者”的|

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//| OR的关系
            string strSource = "abc123xyz";
            Regex myReg 
= new Regex(@"(\d|[a-zA-Z]){3}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //3

            myReg 
= new Regex(@"(_|[a-zA-Z]){3}");
            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count); //2

            Console.ReadLine();
        }
    }
}

5、组与非捕获组

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
string strSource = "think in c# deeply,and think in javascript deeply";
            Regex myReg 
= new Regex(@"^think ([a-z]{2}) c# ([a-z]{4,}),and think \1 javascript \2$");
            
//正则表达式引擎会记忆()中匹配到的内容,作为一个"组",并且可以通过索引的方式进行引用.
            
//表达式中的"\1",用于反向引用表达式中出现的第一个组,\2则依此类推。

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                
int i = 1;
                
foreach (Group group in myReg.Match(strSource).Groups)
                {
                    Console.WriteLine(
"group"+i.ToString()+" value:" + group.Value);//输出组中的内容,第二组是in,第三组是deeply
                    i++;
                }
            }
            
//获取组中的内容,注意,第一组是整个变量strSource的值,从第二、三组才匹配我们想要的in和deeply

            Console.WriteLine(
"--------------------------------");

            myReg 
= new Regex(@"^think (?<g1>[a-z]{2}) c# (?<g2>[a-z]{4,}),and think \1 javascript \2$");
            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"group1 value:" + myReg.Match(strSource).Groups["g1"].Value);//输出:in
                Console.WriteLine("group2 value:" + myReg.Match(strSource).Groups["g2"].Value);//输出:deeply
            }
            
//根据组名进行索引.使用以下格式为标识一个组的名称(?<groupname>…)。


            Console.WriteLine(
"--------------------------------");

            strSource 
= "think in c# deeply deeply";
             myReg 
= new Regex(@"([a-z]{4,}) \1");
             
if (myReg.IsMatch(strSource))
             {
                 
string tmpStr = myReg.Replace(strSource, "$1");
                 Console.WriteLine(
"result:" + tmpStr);//输出:deeply
             }
            
//删除原字符串中重复出现的“deeply”。在表达式之外,使用“$1”来引用第一个组,下面通过组名来引用:

             myReg 
= new Regex(@"(?<g1>[a-z]{4,}) \1");
             
if (myReg.IsMatch(strSource))
             {
                 
string tmpStr = myReg.Replace(strSource, "${g1}");
                 Console.WriteLine(
"result:" + tmpStr);//输出:deeply
             }

             Console.WriteLine(
"--------------------------------");

             myReg 
= new Regex(@"^think in c# (?:[a-z]{4,})$");
             
if (myReg.IsMatch(strSource))
             {
                 Console.WriteLine(
"group1 value:" + myReg.Match(strSource).Groups[1].Value);//输出:空
             }
            
//在组前加上“?:”表示这是个“非捕获组”,即引擎将不保存该组的内容。

            Console.ReadLine();
        }
    }
}

6、贪婪与非贪婪
正则表达式的引擎是贪婪的,只要模式允许,它将匹配尽可能多的字符。通过在“重复描述字符”(*,+)后面添加“?”,可以将匹配模式改成非贪婪。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
string strSource = "think in c# deeply,and think in javascript deeply";
            Regex myReg 
= new Regex(@".*ly");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);//输出:think in c# deeply,and think in javascript deeply
            }

            Console.WriteLine(
"--------------------------------");

            myReg 
= new Regex(@".*?ly");//通过在*,+等后面添加“?”,将匹配模式改成非贪婪

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//2 这里匹配结果是两项

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);//输出:think in c# deeply
            }

            Console.ReadLine();
        }
    }
}

7、正向预搜索、反向预搜索
正向预搜索声明格式:正声明 “(?=…)”,负声明 “(?!...)” ,声明本身不作为最终匹配结果的一部分。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
string strSource = "think in javascript deeply";
            
//myReg中的正声明表示必须保证在至少5个字母的后面必须紧跟着“ in”(in前有一个空格)
            Regex myReg = new Regex(@"[a-z]{5,}(?= in)");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }

            Console.WriteLine(
"--------------------------------");

            
//myReg中的负声明表示必须保证在至少5个字母的后面不能跟有“ in”(in前有一个空格)
            myReg = new Regex(@"[a-z]{5,}(?! in)");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//2

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }

            Console.ReadLine();
        }
    }
}

反向预搜索声明格式:正声明“(?<=)”,负声明“(?<!)”,声明本身不作为最终匹配结果的一部分。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {

            
string strSource = "think in c# bright,think in javascript deeply";
            
//myReg中的反向正声明表示必须保证在6个字母组合的前面必须紧跟着至少5个字母的组合
            Regex myReg = new Regex(@"(?<=[a-z]{5,})(\s[a-z]{6})");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }

            Console.WriteLine(
"--------------------------------");

            
//myReg中的反向负声明表示必须保证在6个字母组合的前面必须紧跟着处至少5个字母的组合
            myReg = new Regex(@"(?<![a-z]{5,})(\s[a-z]{6})");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }
        }
    }
}

 
8、回溯与非回溯
使用“(?>…)”方式进行非回溯声明。由于正则表达式引擎的贪婪特性,导致它在某些情况下,将进行回溯以获得匹配。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace MyCsStudy
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
string strSource = "think in c# deeply,think in javascript deeply";
            
//由于"*"的贪婪特性,将一直匹配到字符串的最后,随后匹配“ly,”,但在匹配“,”时失败,此时引擎将回溯,并在“ly,”处匹配成功
            Regex myReg = new Regex(@".*ly,");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//true
            Console.WriteLine(myReg.Matches(strSource).Count);//1

            
if (myReg.IsMatch(strSource))
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }

            Console.WriteLine(
"--------------------------------");

            
//非回溯,无匹配项
            myReg = new Regex(@"(?>.*)ly,");

            Console.WriteLine(myReg.IsMatch(strSource)); 
//false
            Console.WriteLine(myReg.Matches(strSource).Count);//0

            
if (myReg.IsMatch(strSource))//不匹配
            {
                Console.WriteLine(
"match:" + myReg.Match(strSource).Value);
            }
            
else Console.WriteLine("no match result");
           
            Console.ReadLine();
        }
    }
}

9、小结
关于正则表达式有很多书籍专门讲解它的高级应用,比如在搜索引擎,词库等方面的应用。读者可按需要自己去买来看看。按照笔者的经验,这个东西学起来不难,用起来也很灵活,当然忘得也很快。关于正则表达式还有很多高级应用这里没有也不可能一一列举,需要注意的是,有些需求要做到精确匹配比较困难,只能退而求其次,保证比较精确的匹配。比如url的验证,这里就不举例了。

转载于:https://www.cnblogs.com/jeffwongishandsome/archive/2010/04/08/1512556.html

<think>我们正在讨论C#中的FuncAction委托。根据引用内容,我们知道: - Action委托用于封装没有返回值的方法(void方法) - Func委托用于封装有返回值的方法 引用[1]提到:Func委托封装了GetNumberConcatenateStrings方法(这些方法有返回值),而ActionFunc区别在于返回值。 引用[2]明确指出:Action委托用于没有返回值的方法,Func委托用于有返回值的方法。 引用[3]也说明:Action委托指向没有返回值的方法,而Func委托用于有返回值的方法。 引用[4]展示了一个使用Action<string>的事件,该事件在Form2关闭时触发,并传递一个字符串参数(没有返回值)。 因此,我们可以总结如下: **区别:** 1. **Action**: 用于表示没有返回值的方法。它可以有0到16个输入参数。 2. **Func**: 用于表示有返回值的方法。它的最后一个泛型参数表示返回类型,可以有0到16个输入参数(加上一个返回类型参数)。 **使用场景:** - 当需要封装一个没有返回值的方法时,使用Action。 - 当需要封装一个有返回值的方法时,使用Func。 **示例:** 下面我们通过示例来展示两者的使用。 ### Action委托示例 ```csharp // 定义一个没有返回值的方法,接受一个字符串参数 static void PrintMessage(string message) { Console.WriteLine(message); } // 使用Action委托 Action<string> actionExample = PrintMessage; actionExample("Hello, Action!"); // 输出: Hello, Action! // 也可以使用匿名方法 Action<string> actionAnon = (msg) => Console.WriteLine(msg); actionAnon("Hello from anonymous method!"); ``` ### Func委托示例 ```csharp // 定义一个返回两个整数的方法 static int Add(int a, int b) { return a + b; } // 使用Func委托(两个输入参数,一个返回值) Func<int, int, int> funcExample = Add; int result = funcExample(3, 5); // 返回8 Console.WriteLine(result); // 使用匿名方法 Func<int, int, int> funcAnon = (x, y) => x + y; int result2 = funcAnon(10, 20); // 返回30 Console.WriteLine(result2); ``` ### 使用场景说明 - **Action**:常用于事件处理、回调方法(不需要返回值的情况),如引用[4]中的事件`public event Action<string> dataReturned;`。 - **Func**:常用于需要返回结果的回调、LINQ查询(例如Select、Where等方法中)等。 ### 总结 - `Action` `Func` 都是预定义的委托类型,减少了自定义委托的需要。 - `Action` 指向无返回值的方法,`Func` 指向有返回值的方法。 - 它们都支持泛型参数,可以接受多个输入参数(Action最多16个,Func最多16个输入参数+1个返回类型参数)。 §§相关问题§§ 1. 在C#中,如何定义带有多个参数的Action委托? 2. Func委托的最后一个泛型参数代表什么? 3. 为什么说ActionFunc委托可以减少自定义委托使用? 4. 在异步编程中,ActionFunc委托有什么应用?</think>### C# Func Action 委托区别使用示例 在 C# 中,`Action` `Func` 都是预定义的**泛型委托类型**,用于简化方法封装。它们的核心区别在于返回值: 1. **Action 委托** - 用于封装**没有返回值**的方法(相当于 `void` 方法) - 语法:`Action<T1, T2, ...>`(最多支持 16 个输入参数) - 示例: ```csharp // 封装无参数无返回值方法 Action printHello = () => Console.WriteLine("Hello"); printHello(); // 输出: Hello // 封装带参数无返回值方法 Action<string> logMessage = (msg) => Console.WriteLine($"[LOG] {msg}"); logMessage("Action executed"); // 输出: [LOG] Action executed ``` 2. **Func 委托** - 用于封装**有返回值**的方法 - 语法:`Func<T1, T2, ..., TResult>`(最后一个泛型参数 `TResult` 是返回值类型) - 示例: ```csharp // 封装无参数有返回值方法 Func<int> getRandom = () => new Random().Next(1, 100); int num = getRandom(); // 例如返回 42 // 封装带参数有返回值方法 Func<int, int, string> sumToString = (a, b) => (a + b).ToString(); string result = sumToString(3, 5); // 返回 "8" ``` --- ### 关键区别总结 | 特性 | Action 委托 | Func 委托 | |---------------------|---------------------|----------------------| | **返回值** | 无 (`void`) | 有 (`TResult`) | | **参数定义** | 仅输入参数 | 输入参数 + 返回值 | | **典型应用场景** | 事件处理、回调 | 计算、转换操作 | | **泛型参数示例** | `Action<string>` | `Func<int, string>` | --- ### 实际应用场景 #### 场景 1:事件处理(Action) ```csharp // 窗体事件(无返回值) public event Action<string> DataProcessed; // 触发事件 DataProcessed?.Invoke("Processing complete"); // 引用[4] ``` #### 场景 2:LINQ 查询(Func) ```csharp List<int> numbers = new() { 1, 2, 3, 4 }; // 使用 Func 转换数据 Func<int, bool> isEven = x => x % 2 == 0; var evenNumbers = numbers.Where(isEven); // 返回 [2, 4] ``` #### 场景 3:回调机制 ```csharp // 使用 Action 作为完成回调 void DownloadData(Action<string> onComplete) { // 模拟下载 onComplete("Data downloaded"); } // 调用 DownloadData(result => Console.WriteLine(result)); // 输出: Data downloaded ``` --- ### 为什么使用它们? 1. **减少委托定义**:无需手动声明 `delegate` 类型 ```csharp // 旧方式(需要自定义委托) delegate int OldDelegate(int a, int b); // 新方式(直接使用 FuncFunc<int, int, int> addFunc = (a, b) => a + b; // 引用[3] ``` 2. **支持 Lambda 表达式**:与匿名方法无缝结合 3. **提高代码通用性**:如 LINQ 异步编程中广泛使用 > 关键原则:需要返回值时用 `Func`,仅需执行操作时用 `Action`[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值