1、自动属性

之前的实现方式:

private int  id;
public int Id
{
set {id = value;}
get {return id;}
}

现在可通过自动属性实现: public int Id{ get;  set; }

2、推断类型(var):推断类型,又名隐式类型,使用var关键字,可以是内置类型、匿名类型、用户定义类型或 .NET Framework 类库中定义的类型。

从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型 var。隐式类型的本地变量是强类型变量,但由编译器确定类型。

下面的两个 i 声明在功能上是等效的:

var i = 10; // implicitly typed
int i = 10; //explicitly typed

使用 var 声明局部变量的各种方式:

// i is compiled as an int
var i = 5; // s is compiled as a string
var s = "Hello"; // a is compiled as int[]
var a = new[] { 0, 1, 2 }; // expr is compiled as IEnumerable<Customer>
// or perhaps IQueryable<Customer>
var expr =
from c in customers
where c.City == "London"
select c; // anon is compiled as an anonymous type
var anon = new { Name = "Terry", Age = 34 }; // list is compiled as List<int>
var list = new List<int>();

小结:

[1]变量必须在声明的同时被初始化,编译器要根据初始化值推断类型;初始化表达式不能是null;例如不能用var a; 或 var a = null;声明。

[2]该类型在第一次声明时已具有类型。例如:var a=1; a="";  //报错,因为前面var a=1;已经推断出a为整形了,所以不能把字符串赋值给整形
[3]var 变量不能作为全局变量使用,被声明的变量是一个局部变量,而不是静态或实例字段;
[4]初始化不是一个匿名函数;
[5]语句中只能声明一次变量,声明后不能更改类型;
[6]赋值的数据类型必须是可以在编译时确定的类型;
3、参数默认值

C#4.0的新特性:可选参数、命名参数、参数数组。

[1]、可选参数,是指给方法的特定参数指定默认值,在调用方法时可以省略掉这些参数。

但要注意:

(1)可选参数不能为参数列表的第1个参数,必须位于所有的必选参数之后(除非没有必选参数);

(2)可选参数必须指定一个默认值,且默认值必须是一个常量表达式,不能为变量;

(3)所有可选参数以后的参数都必须是可选参数。

[2]、命名参数, 是指通过命名参数调用,实参顺序可以和形参不同。

[3]、参数数组,通过关键字params定义参数数组。调用时可以传入个数不同的实参,具备很好的灵活性。

实例如下:

//可选参数
void DefaultPara(int age=10,string name="Jack")
{
Console.WriteLine(age+":"+name);
} 测试:
defaultPara(); //输出10:Jack
defaultPara(15); //输出15:Jack
defaultPara(20,"Mary"); //输出20:Mary

注意:只给name参数时,应用参数名;例如DefaultPara(name:"John");  //输出10:John;

//可选参数
static int Add(int a, int b = )
{
return a + b;
} //参数数组,关键字params
static int Add(params int[] p)
{
int sum=;
foreach (int i in p)
sum += i;
return sum;
} static void Main(string[] args)
{
//可选参数
Console.WriteLine(Add()); //b=1
Console.WriteLine(Add(, )); //a=1, b=3 //通过命名参数调用,实参顺序可以和形参不同
Console.WriteLine(Add(b:, a:)); //调用使用了参数数组的方法
Console.WriteLine(Add(, ,));
Console.WriteLine(Add(, , ,));
Console.ReadKey();
}

4、对象、集合初始化器

public class User {

public string name{ get;  set; }

public int age{ get;  set; }

}

旧实现方式:User user = new User(); user.name = "Jack"; user.age = 18;

[1]对象初始化器:User user = new User(){name:"Jack",age:18};

[2]集合初始化器:List<User> list = new List<User>(){new user(){name:"Jack",age:18}, new user(){name:"Mary",age:21}}

[3]数组初始化器:string[] str = {"123", "456", "789"}

5、匿名类:属性名字或顺序不同生成不同的泛型类,属性为只读

[1]可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。

public class User
{
public int Age{ get; set; }
public string Name{ get; set; }
} //初始化对象
User user0 = new User { Age = 18, Name = "Jack" };
User user1 = new User() { Age = 16, Name = "Mary" }; //用匿名类
var user2 = new { Age = 18, Name = "John" };

可以看到new后面没有跟类类型,此定义了一个匿名类,不需要知道这个类的名字,只能读取属性,不能改写属性值

例如: string name = user.Name;//正确    user.Name = "Jam";//错误

[2]如果两个或更多个匿名类型在同一程序集中具有相同数量属性和属性类型,在相同的顺序中,则编译器会将这些匿名类型视为同一的类型。 它们共享同一编译器生成的类型信息。即

(1)如果另一个 匿名类对象 的属性类型和顺序 一样,那么会共用同一个匿名类!

var user3= new { age = 19, name = "John0" };   Console.WriteLine(user3.GetType() == user2.GetType());//true

(2)如果另一个匿名类对象的属性名称和顺序一样,但类型不一样,那么还是使用相同的匿名类,创建对象时传入不同的类型参数

var user4= new { age = "19", name = "John1"  };    Console.WriteLine(user4.GetType()==user2.GetType());//true

(3)如果属性名相同,类型相同,但是顺序不同,那么也会重新创建一个匿名类!

var user5 = new { name = "John2", age = 19 };     Console.WriteLine(user5.GetType() == user2.GetType());//false

6、匿名方法:匿名方法只是在我们编写的源代码中没有指定名字而已,其实编译器会帮匿名方法生成一个名字,然而就是因为在源代码中没有名字,所以匿名方法只能在定义的时候才能调用,在其他地方不能被调用(匿名方法把方法的定义和方法的实现内嵌在一起),

      在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。

//声明委托
delegate void Printer(string s); class TestClass
{
static void Main()
{
// 使用匿名方法实例化委托
Printer p = delegate(string j)
{
System.Console.WriteLine(j);
};
// 调用委托
p("The delegate using the anonymous method is called."); // 使用命名方法实例化委托
p = new Printer(TestClass.DoWork);
// 调用委托
p("The delegate using the named method is called.");
} // 定义命名方法
static void DoWork(string k)
{
System.Console.WriteLine(k);
}
}
/* Output:
The delegate using the anonymous method is called.
The delegate using the named method is called.
*/

 7、扩展方法扩展方法使我们能够向现有类型"添加"方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。即可以对String,Int,DataRow,DataTable等这些类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码。

扩展方法的定义规则:

[1]扩展方法类必须为静态类;

[2]拓展方法被定义为静态方法,但它们是通过实例方法语法进行调用的;

[3]它们的第一个参数指定该方法作用于哪个类型(不可为指针类型),并且该参数以 "this" 修饰符为前缀;

[4];第一个参数不可有任何其他修饰符(ref/out);

[5]仅当你使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。

静态方法需类型实例化后方可调用,"this"指实例化对象。

示例如下:

namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
} //调用该扩展方法:
using ExtensionMethods;
string s = "Hello Extension Methods";
int i = s.WordCount();

如果你确实为给定类型实现了扩展方法,请记住:

[1]如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用(类型中定义方法优先于扩展方法)。

[2]在命名空间级别将扩展方法置于范围中。(即引入命名空间)

 8、系统内置委托

C#在公共语言运行时(CLR)环境中系统为我们内置了一些常用的委托,包括Action类的委托、Func类的委托、Predicate<T>委托、Comparison<T>委托等等。以上这些委托的命名空间都是System,所属程序集都是 mscorlib.dll。可以直接利用系统内置委托,实例化它们,而不必显式定义一个新委托并将命名方法分配给该委托。

[1]Action类的委托:无返回类型的委托

(1).Action委托 封装一个方法,该方法不具有参数并且不返回值

(2).Action<T>委托 封装一个方法,该方法只有一个参数并且不返回值

(3).Action<T1,T2>委托 封装一个方法,该方法具有两个参数并且不返回值

…… ……

(17).Action<T1,T2,T3,...,T14,T15,T16>委托 封装一个方法,该方法具有16个参数并且不返回值

实例:

static void Main(string[] args)
{   
#region Action<T>委托示例
//需求:打印出整型集合list的元素
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Action<T> 委托实例
Action<int> concat1 = delegate(int i) {
Console.WriteLine(i);
};
list.ForEach(concat1);
//将 lambda 表达式分配给 Action<T> 委托实例
Action<int> concat2 = (i => Console.WriteLine(i));
list.ForEach(concat2);
Console.ReadKey();   
#endregion
}

总结:Action类的委托最少可以传入0个参数,最多可以传入16个参数,参数类型皆为逆变,并且不返回值。

[2]Func类的委托:

(1).Func(TResult)委托封装封装一个不具有参数但却返回 TResult 参数指定的类型值的方法

(2).Func(T,TResult)委托 封装一个具有一个参数并返回 TResult 参数指定的类型值的方法

(3).Func(T1,T2,TResult)委托 封装一个具有两个参数并返回 TResult 参数指定的类型值的方法

…… ……

(17).Func<T1,T2,T3,...,T14,T15,T16,TResult>委托 封装一个方法,该方法具有16个参数,并返回TResult参数所指定的类型的值

实例:

static void Main(string[] args)
{
#region Func<T,TResult>委托示例
//需求:查找整型集合list中大于3的所有元素组成的新集合,并打印出集合元素
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Func<T,TResult> 委托实例
Func<int, bool> concat1 = delegate(int i) { return i > 3; };
var newlist1 = list.Where(concat1).ToList();
//将 Lambda 表达式分配给 Func<T,TResult> 委托实例
Func<int, bool> concat2 = i => i > 3;
var newlist2 = list.Where(concat2).ToList();
newlist1.ForEach(i => Console.WriteLine(i.ToString()));
newlist2.ForEach(i => Console.WriteLine(i.ToString()));
Console.ReadKey();
#endregion
}

总结:Func类的委托最少可以传入输入泛型参数(in,逆变) 0个,最多可以传入输入泛型参数(in,逆变) 16个,传入的输出泛型参数(out,协变)有且只有一个,这个类型是此委托封装的方法的返回值类型。

[3]Predicate<T>委托:表示定义一组条件并确定指定对象是否符合这些条件的方法

static void Main(string[] args)
{
#region Predicate<T>委托示例
//需求:查找整型集合list中大于3的所有元素组成的新集合,并打印出集合元素
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Predicate<T> 委托实例
Predicate<int> concat1 = delegate(int i) { return i > 3; };
var newlist1 = list.FindAll(concat1);
//将 lambda 表达式分配给 Predicate<T> 委托实例
Predicate<int> concat2 = (c => c > 3);
var newlist2 = list.FindAll(concat2);
newlist1.ForEach(i => Console.WriteLine(i));
newlist2.ForEach(i => Console.WriteLine(i));        
Console.ReadKey();
#endregion
}

总结:Predicate<T>委托封装一个方法,该方法传入一个类型参数,这个参数是指要比较的对象的类型,此类型参数是逆变,同时接收一个参数(该参数就是要按照由此委托表示的方法中定义的条件进行比较的对象,参数的类型就是传入的类型参数的类型),该方法始终返回bool类型的值。如果该对象符合由此委托表示的方法中定义的条件,则为 true;否则为 false。

[4]Comparison<T>委托:表示比较同一类型的两个对象的方法

static void Main(string[] args)
{
#region Comparison<T>委托示例
//需求:将整型集合list中的所有元素倒序排列打印出来
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Comparison<T> 委托实例
Comparison<int> concat1 = delegate(int i, int j) { return j - i; };
//将 lambda 表达式分配给 Comparison<T> 委托实例
Comparison<int> concat2 = (i, j) => j - i;
list.Sort(concat1);
list.ForEach(c => Console.WriteLine(c.ToString()));
list.Sort(concat2);
list.ForEach(c => Console.WriteLine(c.ToString()));        
Console.ReadKey();
#endregion
}

总结:Comparison<T>委托封装一个方法,该方法传入一个类型参数,这个参数是指要比较的对象的类型,此类型参数是逆变,同时接收两个同类型的参数(这两个参数就是要比较的两个对象,参数的类型就是传入的类型参数的类型),始终返回int类型的值,即一个有符号整数,指示 x 与 y 的相对值:

(1)负数(小于0):x小于y;  (2)零(0):x等于y;(3)正数(大于0):x大于y;

C#编程的语法积累(一)的更多相关文章

  1. C#编程语法积累(二)

    9.Lambda表达式 [1]Lambda表达式缩写推演,如下图: [2]Lambda语句:=>右边有一个语句块(大括号"{}"):Lambda表达式:=>右边只有一个 ...

  2. 电脑小白自学软件编程-.Net语法基础之循环语句,纯技巧干货

    写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用视频. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是不在话下. 本教程是基础教程,适合任何有志于学习软件开发的 ...

  3. linux之shell编程基本语法

    Shell是用户与内核进行交互操作的一种接口,目前最流行的Shell称为bash Shell.Shell也是一门编程语言<解释型的编程语言>,即shell脚本<就是在用linux的s ...

  4. Bash shell编程的语法知识点(1)

    Bash shell脚本编程知识点如下(初学,不全,欢迎讨论补充): shell简介 脚本的简单介绍 变量和引用 算术运算 交互式编程 选择判断 条件测试 循环 函数 shell简介 shell是一种 ...

  5. Shell 脚本编程 基本语法:

    Shell 脚本编程语法: 注: 文章来源 http://www.cnblogs.com/yunquan/p/6821850.html 视频来源:https://www.bilibili.com/vi ...

  6. 怎样用 Bash 编程:语法和工具

    让我们通过本系列文章来学习基本的 Bash 编程语法和工具,以及如何使用变量和控制运算符,这是三篇中的第一篇. Shell 是操作系统的命令解释器,其中 Bash 是我最喜欢的.每当用户或者系统管理员 ...

  7. PHP CLI编程基础知识积累(进程、子进程、线程)

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...

  8. 学习笔记(10) : Socket 编程典型代码积累

    网络编程实现的机制:   服务器端: 申请一个socket 绑定到一个IP地址和端口上 开启侦听,等待接受连接   客户端: 申请一个socket 连接服务器(指明IP.端口)   服务器端: 接收到 ...

  9. shell编程基础语法

    创建文件:touch aaa.sh 把文件变成可执行的命令: chmod +x /Users/dream-mac/Desktop/aaa.sh (这里是文件路径,如果在当前路径下,只需要把文件名写到这 ...

随机推荐

  1. .NET面试题系列(十四)锁

    锁 分布式锁 如何解决分布式锁超时问题 我们可以让获得锁的线程开启一个守护线程,用来给快要过期的锁“续航” 当过去了29秒,线程A还没执行完,这时候守护线程会执行expire指令,为这把锁“续命”20 ...

  2. 14. Spring Boot的 thymleaf公共页抽取

    5).CRUD-员工列表实验要求:1).RestfulCRUD:CRUD满足Rest风格:URI: /资源名称/资源标识 HTTP请求方式区分对资源CRUD操作   普通CRUD(uri来区分操作) ...

  3. sock_ntop.c

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in ...

  4. 前段clam安装

    前端模块化协同开发解决方案 —— clam 1. 打开后直接看最后一条https://blog.csdn.net/zhangwenwu2/article/details/581720422. node ...

  5. luogu P1070 道路游戏

    传送门 这里设\(f_i\)表示时刻\(i\)的答案 转移的话在\([i-p+1,i-1]\)之间枚举j,然后考虑从哪个点走过来 复杂度为\(O(n^3)\) // luogu-judger-enab ...

  6. 7、完整版的strcpy函数

    char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) && (strSrc != ...

  7. 【Gradle】Gradle环境配置

    Windows环境 下载 作者下载的是gradle-4.1-all.zip,下载地址:http://services.gradle.org/distributions 环境配置 GRADLE_HOME ...

  8. Toy Train(贪心)

    题目链接:http://codeforces.com/contest/1130/problem/D1 题目大意:给你n个点,然后m条运输任务,然后问你从每个点作为起点是,完成这些运输任务的最小花费?每 ...

  9. 对numpy中shape的理解

    from:http://blog.csdn.net/by_study/article/details/67633593 环境:Windows, Python3.5 一维情况: >>> ...

  10. php学习之mysqli的面向对象

    // mySqlTool.php  封装好的工具类 <?php class SqlTool{ private $conn; private $host="localhost" ...