C#面向对象12_LINQ语法

2021-07-12 15:04

阅读:491

标签:list   main   ati   语句块   lib   正方形   隐式   一个   用户   

LinQ语法

LinQ.net FrameworkC#语言从3.0版本开始,所支持的一系列新语法的特性。它使语法更简洁,甚至可以说是对C#面向对象的一种“改革、创新”。它是一个新的语法体系。

var 关键字

var关键字是.net framework 3.0的新增特性,称为隐式类型或匿名变量。

var关键字根据赋值号(=)或初始化语句右侧的构造函数或表达式来推断出变量的类型。它可以用推断值类型、引用类型、用户自定义类型。

 

匿名变量

示例:

  var i = 10;

            i += 100;

            var s = "abc";

            s += "def";

            Console.WriteLine(i.GetType().ToString());

            Console.WriteLine(s.GetType().ToString());

不要将var误解为是一种(较自动的独立的)类型,它是用值来推断变量的类型。

程序在执行之前都会被编译为能够被机器执行的代码,而在这个转换过程中var会自动被“翻译”为intstring等具体的数据类型。

 

varobject类型区别

使用varobject的性能更高,因为var与直接写intstring等具体的类型几乎没有区别的。但是object必须要装箱拆箱了,这个过程肯定会对性能有所影响。

 

varforeach

遍历数组

  //string[] sArr = new string[] { "tom","jerry","kitty","marry"};

            int[] sArr = new int[] {1,2,3,4,5,6,7 };

            foreach (var item in sArr)

            {

                Console.WriteLine(item);

            }

遍历集合

  Listfloat> sArr = new Listfloat>();

            sArr.Add(343.656f);

            sArr.Add(98.34f);

            sArr.Add(65.8f);

            sArr.Add(865);

            foreach (var item in sArr)

                Console.WriteLine(item);

注意事项

1、在使用var关键字定义变量的时候,必须对变量赋值,而不能这样:
var s ; 因为只有给变量赋值var才能够推断出这个变量的类型。

2、一旦用var完成对变量的定义,就不能再给变量赋与初始值类型不同的值了。因为第一次推断类型之后,变量的类型就固定了。

3、只能用var来定义局部变量,不能用来定义类的成员变量,也不能用来定义方法的传入值与返回值的类型。

4varobject是不同的,var与直接定义的强类型变量完全一样的。

 

示例:

var v1;     //没有赋初值

var v2=v2-1;     //初始化表达式不能包含变量本身

var v3={32,65,87,54};     //不能直接使用数据初始值作用初始化表达式

var v4=null;     //null无法用于推导出变量的类型

class student {

    public var i = 10;  //不能用var定义类成员

}

匿名类型

之前我们讲过,对象是属性某一个类的实例,但是对于匿名类型而言,这一点并不成立,就是说我们可以凭空创建一个对象而它不属于任何类。

示例:

   string myName = "小明";

            var obj = new {

                myTitle="我是一个匿名类型",

                myAge=18,

                mySorce=new int[]{100,99,98,97},

                myName

            };

            Console.WriteLine(obj.myAge.GetType());

            Console.WriteLine("我叫{0},今年{1},语文成绩{2}", obj.myName, obj.myAge, obj.mySorce[2]);

1、在关键字之后直接定义了对象的属性,并且必须为这些属性赋值。

2、不需要指定访问修饰符,我们可以在对象创建之后直接访问它的属性。

3、如果在匿名类型中加入了一个已赋值的变量作为属性值的话,就不需要在定义时再次赋值了,并且,该变量的变量名就是属性名,变量值就是属性值。

4、匿名类型的属性不需要明确的指定类型,其类型会被推导出来。(因此属性必须得有值。)

 

 初始化器

对象初始化器。初始化(实例化)的过程,也就是对一个对象赋初值的过程,对象初始化器是对构造函数的一种补充和替代。

示例1

student tom = new student() { name="汤姆克鲁思", age=35,height=180, sex=true };

            Console.WriteLine(tom.name+"---"+tom.age+"----"+tom.height);

    class student {

        public string name{get;set;}

        public int age;

        public float height;

        public bool sex;

    }

示例2,同时使用对象初始化器和构造函数:

student tom = new student("汤姆克鲁思") { age = 35, height = 180, sex = true, name = "汤姆布鲁斯" };

            Console.WriteLine(tom.name+"---"+tom.age+"----"+tom.height);

    class student {

        public student(string name) { this.name = name; }

        public string name{get;set;}

        public int age;

        public float height;

        public bool sex;

    }

集合初始化器

能够简便的在初始化集合时赋值初值

示例:

    //List iList = new List(new int[]{1,2,3,4,5,6,7});

 //它用一个实现了IEnumerable接口的数组传入List的构造函数来为集合赋初值。

            var iList = new Listint> { 1,2,3,4,5,6,7};

 //这里是集合初始化器

            foreach (var i in iList)

                Console.WriteLine(i);

数组初始化器

            //var arr = new[] { 1,2,3,4,5};

            var arr = new int[] { 1, 2, 3, 4, 6 };

            foreach (var i in arr)

                Console.WriteLine(i);

var定义的数组依然是满足数组三要素的。

小练习:

var定义int string bool double long类型的变量,并打印出其值和类型。

var 定义一个cat匿名类型的实例,要求有agecolornameisBoSi ( bool) 属性,并显示出这只猫的信息。

用初始化器来定义一个存放float型数据的List泛型集合,并且遍历显示,临时变量用var定义

用初始器来定义一个存放float开始数据的List泛型集合,并且遍历显示。

创建一个cat类,要求有age colornameisBoSi ( bool) 字段,用对象初始化器实例化一个猫的对象同时给猫的字段赋初值,不能使用构造函数。

用集合初始化器来定义一个存放上题cat类的实例对象的List泛型集合。并且,初始化集合的时候所使用的每一项的值都是由对象初始器来实例化的cat对象。

 

匿名方法与Lambda表达式

匿名方法

匿名方法没有具体的方法名,它不隶属于某个类,而是完全依赖于委托而存在的一种方法。它的定义过程,相当于是在实例化委托时,或者对委托赋值时,向委托中存入一个没有方法名的方法。 

示例1

  delegate void MyDelegate(int i);

    class Program

    {

        static void Main(string[] args)

        {

            //用delegate关键字代替了方法名

            //方法定义完成之后就直接被存入了委托

            MyDelegate mydel = delegate(int i)

            {

                Console.WriteLine("我今天吃{0}碗饭",i);

            };

            mydel(8);

        }

    }

示例2,有返回值的匿名方法

   delegate string MyDelegate(int i);

    class Program

    {

        static void Main(string[] args)

        {

            //用delegate关键字代替了方法名

            //方法定义完成之后就直接被存入了委托

            MyDelegate mydel = delegate(int i)

            {

                return "我今天吃"+i+"碗饭";

            };

            Console.WriteLine( mydel(8));

        }

    }

lambda表达式

我们可以将它看做是匿名方法的简单升级版。

delegate string MyDelegate(int i);

    class Program

    {

        static void Main(string[] args)

        {

            //用delegate关键字代替了方法名

            //方法定义完成之后就直接被存入了委托

            MyDelegate mydel = delegate(int i)

            {

                Console.WriteLine("我今天吃" + i + "碗饭");

                return "我今天吃" + i + "碗饭";

            };

            //lambda表达式,第一个圆括号中,放的是传入参数(如果没有传入参数,得写一个空括号)。 =>之后的{}花括号中,就是这个方法的具体代码。

            mydel += (int i) =>

            {

                Console.WriteLine("我吃了" + i + "碗面");

                return i.ToString();

            };

            mydel(5);

        }

    }

语法格式

lambda表达式在本质上就是匿名方法,因此它必须赋值到一个委托实例中。

委托实例 =(传入参数列表)=>{方法的代码};

其中:传入参数列表就是方法的传入参数,即使没有传入参数也要写一个空括号。

简化写法

 delegate void delTest();

    delegate int delTest2(int i);

    class Program

    {

        static void Main(string[] args)

        {

            delTest d1;

            //当lambda表达式中只有一条语句时,可以不加{}花括号

            d1 = () =>Console.WriteLine("明天放假");

            d1();

            delTest2 d2;

            //第一个圆括号中的传入参数,可以省略类型,程序会自动推断出其类型

            //只要存在一个计算结果,可以不写return关键字,它会自动返回这个计算结果。

            //d2 = (i) => i + 10;

            d2 = i => i + 10;       //圆括号也可以省略

            Console.WriteLine(d2(8));

        }

}

 

小练习:

定义一个Lambda表达式,其作用是两个字符串连接起来并返回,需要写{}return

定义一个Lambda表达式,其作用是两个数相乘并返回结果,不需要写{}

定义一个Lambda表达式,其作用是返回当前时间,不需要写{}return

 

扩展方法

在类的外部向类中添加方法的一种途径,通常用天向一些已经完成编译或不便于修改的类(比如 密封类)之中添加方法。

示例

static class Program

{

static void Main(string[] args)

{

string ss = "tom";

ss.PrintMyWord2222("----");

}

public static void PrintMyWord2222(this string val, string v2)

{

Console.WriteLine(val+v2);

}

}

注意事项:

扩展方法必须定义在一个非泛型、非嵌套的静态类中。

扩展方法本身必须是一个静态方法。

扩展方法至少要有一个传入参数。

第一个参数必须添加this关键字,这个参数代表调用这个方法的对象本身。

第一个参数不能有其他修饰符(比如:refout

扩展方法通常不建议大规模使用,因为它会降低程序的规范和可读性。

 

小练习:

int类型添加一个计算正方形面积的扩展方法。

float类型添加一个计算圆面积的扩展方法。

定义一个student类,包含语文、数学、英语成绩,然后对其添加一个计算平均分的扩展方法。

在上题的student类中添加一个计算总分的方法,而这个方法用来执行一个委托实例,该委托实例是由方法传入参数传递进来的。

static class Program

{

static void Main(string[] args)

{

student tom = new student() { YW = 89, SX = 98, EN = 83 };

//定义了一个传入三个参数并返回三个数之合的匿名方法

delCount delcc = (a, b, c) => a + b + c;

//将包含了匿名方法的委托传入了getCount()方法,在getCount()方法中执行这个委托。

Console.WriteLine( tom.getCount(delcc));

}

}

public delegate float delCount(float f1,float f2,float f3);

class student {

public float YW;

public float SX;

public float EN;

public float getCount(delCount dc) {

//接收一个变量型态的委托dc

return dc(this.YW,this.SX,this.EN);

//给dc加一个括号和传入参数,让其以函数形态来执行。

}

}

迭代器

它在本质上是一个接口IEnumerable,实现了个接口的集合都允许通过foreach来进行遍历。这个接口要求实现GetEnumerator()方法:

static void Main(string[] args)

{

foreach (var i in GetItem())

{

Console.WriteLine("-----遍历值----" + i);

}

//GetItem(); 没有返回任何结果

}

static IEnumerablestring> GetItem() 

{

Console.WriteLine("迭代器返回1");

yield return "tom";

Console.WriteLine("迭代器返回2");

yield return "jerry";

Console.WriteLine("迭代器返回3");

yield return "hello kitty";

}

通过迭代器来遍历集合,可以通过我们的程序设计让集合中的内容不全部存储在内存中。

yield关键字

在迭代器的语句块中,在一次循环结束的时候,发送迭代结束的信息,通过它来确定每一次循环结束的位置。

C#面向对象12_LINQ语法

标签:list   main   ati   语句块   lib   正方形   隐式   一个   用户   

原文地址:https://www.cnblogs.com/yigegaozhongsheng/p/9602545.html


评论


亲,登录后才可以留言!