难过的吃手手

  博客园  :: 首页  :: 新随笔  ::  :: 订阅 订阅  :: 管理

1.委托

  委托是一种引用类型,表示对具有 特定参数列表 和 返回类型 的方法的引用

  可以通过委托实例调用方法,也可以将委托作为方法的参数传递给其他方法。

  委托提高了程序的可扩展性。

  委托声明决定了可由该委托引用的方法,委托可指向一个与其具有相同签名的方法:

  语法:

public delegate <return type> <delegate name>(paramater list)

  示例:

public delegate string Dele(string s);

  同时,能被委托调用的方法要满足以下条件:

  (1)方法的返回值类型必须和委托定义的一致

  (2)方法的参数类型,个数和顺序必须和委托定义一致

  (3)大部分的时候被委托执行的方法要声明为静态方法

public delegate string Dele(string name);

static void main(string[] agrs){
    
    //实例化委托,运行d时相当于运行了show1()方法
   //Dele d=  new Dele();
  // d.Invoke("张三");    
    Dele d = Show1();
    d("张三");

}

public static string Show1(string name){
  Console.writeLine(name+"你好!");    
  return name;
}
class Program
    {


        internal delegate void dele(int x);
        //static int square(int x) => x * x;
        //static int cube(int x) => x * x * x;
        static void Main(string[] args)
        {
            staticDele();
            insDele();
            Console.ReadKey();
        }

        private static void Counter(int from, int to, dele de)
        {
            for (int val = from; val <= to; val++)
            {
                // de不为空,则调用回调方法
                if (de != null)
                {
                    de(val);
                }
                //fb?.Invoke(val); 简化版本调用
            }
        }
        private static void staticDele() {
            Console.WriteLine("委托调用静态方法");
            Counter(1,9, null);
            Counter(1, 9, StaticBackConsole);
        }

        private static void insDele() {
            Console.WriteLine("委托调用实例方法");
            Program p = new Program();
            Counter(1, 9, null);
            Counter(1, 5, new dele(InsBackConsole));
        }

        //静态回调方法
        private static void StaticBackConsole(int value)=>Console.WriteLine("number=" + value);


       private static void InsBackConsole(int value) {
            Console.WriteLine("number=" + value);
        }

    }

  多播委托:

  所有的委托实例都具有多播的能力,一个实例可以引用多个目标方法。

  例子:

SomeMethod1 d1 =SomeMethod1;
d1+=SomeMethod2; // =>d1 = d1+SomeMethod2;
调用d1就会调用 SomeMethod1 和 SomeMethod2;

  注意:委托的调用顺序和他们的定义顺序时一致的,也就是从左到右依次执行。

  委托移除调用的方法: d1-=SomeMethod2

 

2.匿名方法

  匿名方法是提供一种传递代码块作为委托参数的技术,没有名称只有主体的方法,

  在匿名方法中不需要指定返回类型,它是从方法主体内return 语句判断的。

  通俗的理解就是,匿名方法就是一个没有名字的方法,和普通方法没有区别,除了没有名字,那就代表

  在别的地方没有办法去调用它,所以匿名方法就是用一次,随写随用,原地站立,不会调来调去。

  这样你就不用写一大堆零碎的小函数了,但是创建匿名方法的前提就是你把它放在一个委托里。

public delegate int dele(int x,int y);
       
        static void Main(string[] args)
        {
            dele d;
            d = delegate (int x, int y) { return x + y; };
            int result = d(2,3);
            Console.WriteLine(result);
            Console.ReadKey();
        }

 3.隐式类型和局部变量

  var关键字允许你声明一个新变量,它的类型是从用来初始化器变量的表达式里隐式的推断的。

  即在声明时,你不需要给它定义类型,它会根据它的初始化器表达式来推断出它的类型,因此,我们称它为隐式类型。

  在for循环初始化语句中,如:

for(var i = 0; i< 10;i++)

  在foreach初始化语句中,如:

foreach(var i in list){...}

  注意事项:在声明的时候必须直接赋值,因为声明依赖于右边的表达式, var i; i=10; 会报错!

  在使用var声明一个局部变量后,它仍然具有强类型,如果再将这个局部变量重新赋值另外一个类型编译器会报错。

4.Lambda表达式

  lambda表达式定义:本质上是一个匿名的函数,编译器在看到lambda之后会在类中自动定义一个新的私有方法。

  语法:(input paramater)=>Expression  在表达式的左侧表示输入的参数,右侧的为相应的运算语句或者判断语句等,可包含函数调用等复杂方式。

  左边的参数列表可以有多个参数,一个参数,或者无参数,参数类型可以隐式或者显式,参数类型可以忽略,因为可以根据使用的上下文判断得出。

  仅当lambda只有一个输入参数时,括号才是可选的,否则括号时必需的。

  例如:

    

(x,y)=>x*y  //多参数,隐式类型=》表达式
x=>x*10        //单参数,隐式类型=》表达式
x=>{return x*10}   //单参数,隐式类型=》语句块int x) => x*10              //单参数,显式类型=>表达式
(int x) =>{return x*10}    //单参数,显式类型=>语句块
()=>Console.WriteLine()    //无参数    

  lambda表达式分为两种:语句lambda和表达式lambda.

5.扩展方法

扩展方法(Extension Methods)是C#3.0时引入的新特性,
最常见的是在LINQ中的使用。
在开发中,我们也可以创建自己扩展方法,使用它来优化类的设计、简化代码。
扩展方法是一种特殊类型的静态方法。对于一个C#类型,如类(包括密封类)、值类型、接口等,

扩展方法可以在不改变该类型源码的前提下,为它的实例提供新的成员。

因此,若要为一个框架或第三方库的某个类型增加辅助功能,通过扩展方法就可以轻而易举地实现,这也是“扩展”的意义所在。
1、创建一个静态类;
2、在其中创建一个静态方法;
3、为这个静态方法添加至少一个参数,并在第一个参数前加上this关键字,
这个关键字会告诉编译器当前方法是一个扩展方法。而这个方法将成为第一个参数所属类型的新成员。
 注意:只有在引用扩展方法所在的静态类的命名空间后,才能使用它;否则,直接调用会编译失败

 

 

  (1)方法所在的类必须是静态的。

  (2)方法也必须是静态的。

  (3)方法的第一个参数必须是你要扩展的那个类型,比如你要给int扩展一个方法,那么第一个参数就是必须是int。

  (4)在第一个参数前面还需有又一个 this 关键字。

  关于扩展方法的使用总结:

  (1)可以向类中添加新方法,而不需要使用继承来创建新类,也不需要修改原有的类。

  (2)如果扩展方法与类中的方法有相同的签名,则扩展方法不会被调用,即扩展方法会被扩展类的同名方法覆盖,所以使用扩展方法我们需要承担

  随时被覆盖的风险。

  (3)扩展方法不能访问扩展类的私有成员

  (4)扩展方法只能使用实例来调用,不能像普通的静态方法一样使用类名调用。

  (5)只有引入扩展方法所在的命名空间后,扩展方法才可以使用。  

 

  

posted on 2022-02-10 08:56  难过的吃手手  阅读(10)  评论(0)    收藏  举报