一、自动属性
C#自动属性可以避免原来这样我们手工声明一个私有成员变量以及编写get/set逻辑
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string DesigCode { get; set; }
}
二、隐式类型 var
var 关键字指示编译器根据初始化语句右侧的表达式推断变量的类型
var str = "大家好";
Type type = str.GetType();
Product p1 = new Product();
Console.WriteLine(str.GetType()+"--"+p1.GetType());//输出类型
三、匿名类
将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。
用来初始化属性的表达式不能为 null、匿名函数或指针类型。
1.用var关键字创建一个匿名类
var person = new { Id = 1, Name = "TOM", DesogCode = "线路" };
2.创建一个匿名集合
var list = new List<Product>() { new Product() { Id = 1, Name = "TOM", DesigCode = "两面同时曝光" } };
3.集合中创建类并输出
List<Product> list = new List<Product>() { new Product { Id = 1, Name = "TOM", DesigCode = "线路" }, new Product { Id = 2, Name = "Jim", DesigCode = "钻孔" } };
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i].Id + "--" + list[i].Name + "--" + list[i].DesigCode);
}
四、对象初始化器与集合初始化器
1.对象初始化器
Product p = new Product() { Id = 2, Name = "TOM", DesigCode = "线路" };
Console.WriteLine(p.Id + "---" + p.Name + "---" + p.DesigCode);
2.集合初始化
List<Product> list = new List<Product>() { new Product { Id = 1, Name = "TOM", DesigCode = "线路" }, new Product { Id = 2, Name = "Jim", DesigCode = "钻孔" } };
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i].Id + "--" + list[i].Name + "--" + list[i].DesigCode);
}
五、扩展方法
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码。
//字符串转换为数字
public static class EString
{
public static int ToInt(this string str)
{
int id;
int.TryParse(str,out id);
return id;
}
}
调用:
string str = "123";
int id = str.ToInt();
扩展方法规定类必须是一个静态类,EString是一个静态类,里面包含的所有方法都必须是静态方法。
msdn是这样规定扩展方法的:“扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。”
EString里有一个ToInt的静态方法,他接收一个自身参数this,类型为string,this string必须在方法参数的第一个位置。
这句话什么意思,即你需要对string扩展一个ToInt方法,this是string实例化后的对象,这可能说的不太清楚,通俗的说就是,扩展方法跟静态类的名称无关,只需要在一个静态类里面定义一个静态方法,第一个参数必须this string开头。
六、委托
委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所指的方法。
委托特点:
1.委托可以当参数传入,当方法需要传入一个参数,而这个参数需要的是一个方法,就可以将委托传入;
2.委托就相当于一个方法:
public delegate void DelSayHi(string name);
DelSayHi del = new DelSayHi(EnglishGreeting);//实例化时传入一个方法
DelSayHi del = EnglishGreeting;//委托直接等于一个方法
3.委托的签名与方法必须一致,就是说返回值与参数必须一致;
例子一、
有两个打招呼方法:
public static void EnglishGreeting(string name)
{
Console.WriteLine("Morning, " + name);
}
public static void ChineseGreeting(string name)
{
Console.WriteLine("早上好, " + name);
}
另外加一个方法,传入委托参数:
public static void Test(string name,DelSayHi del)
{
del(name);
}
委托:
public delegate void DelSayHi(string name);
调用:
Test("张三", ChineseGreeting);
例子二、
1、将一个字符串数组中每个元素都转换成大写
2、将一个字符串数组中每个元素都转换成小写
3、将一个字符串数组中每个元素两边都加上双引号
写一个方法:
public static void ProStr(string[] name,DelProStr del)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = del(name[i]);//变量名等于委托处理,委托处理后返回一个string给变量
}
}
委托:
public delegate string DelProStr(string name);//要有返回值
调用一:
string[] names = { "abCDefg", "HIjkl", "MnOpQ", "RsTUvwXyz" };
//省略方法调用,写匿名方法
ProStr(names,delegate(string name)
{
return name.ToUpper();
//return "\"" + name + "\"";
});
//调用二,传入一个方法调用:
ProStr(names,ProStr2);
//另外写一个方法
public static string ProStr2(string name)
{
return name.ToUpper();
}
七、Lambda表达式
简单来说,编程中提到的lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数
其实,Lambda表达式并没有什么高深的技术,Lambda表达式可以看作是匿名方法的另一种表现形式。Lambda表达式经过反编译后,与匿名方法并没有什么区别。
Lambda 表达式”是一个匿名函数,它可以包含表达式和语句。可用于创建委托。
运算符 =>,该运算符读为“goes to”。
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 Lambda 表达式对于编写 LINQ 查询表达式特别有用。
若要创建 Lambda 表达式,需要在 Lambda 运算符 => 左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。 例如,lambda 表达式 x => x * x 指定名为 x 的参数并返回 x 的平方值。 如下面的示例所示,你可以将此表达式分配给委托类型:
(int x) => x * x; //左侧写参数,右侧写表达式或语句块
x => x * x;//省略参数类型写法
例子一、
public delegate int DelTest(int i);
//第一种写法
DelTest myDel = (int x) => x * x;
//第二种写法
DelTest myDel = (int x) =>
{
return x * x;
};
int j = myDel(5);
例子二:
delegate bool DelDemo(int a, int b);//与类同级
//调用
DelDemo funLambda = (int a, int b) => a > b;
Console.WriteLine(funLambda(1, 3));
例子三,求对象大于20的值:
public class People
{
public int Age { get; set; }
public string Name { get; set; }
}
List<People> people = new List<People>()
{
new People { Age = 21, Name = "开料" },
new People { Age = 21, Name = "钻孔" },
new People { Age = 20, Name = "线路" },
new People { Age = 23, Name = "贴合" }
};
//匿名方法写法:
IEnumerable<People> results1 = people.Where(delegate(People p) { return p.Age > 20; });
//Lambda表达式写法:
IEnumerable<People> results2 = people.Where(People => People.Age > 20);
foreach (var item in results2)
{
Console.WriteLine(item.Name);
}
lambda特点:
1.=> 运算符具有与赋值运算符 (=) 相同的优先级并且是右结合运算;
2.仅当 lambda 只有一个输入参数时,括号才是可选的;否则括号是必需的。 括号内的两个或更多输入参数使用逗号加以分隔;
(x, y) => x == y
有时,编译器难以或无法推断输入类型。 如果出现这种情况,你可以按以下示例中所示方式显式指定类型
(int x, string s) => s.Length > x
使用空括号指定零个输入参数:
() => SomeMethod()
3.在上一个示例中,请注意表达式 Lambda 的主体可以包含一个方法调用。 但是,如果要创建在 .NET Framework 之外计算的表达式目录树(例如,在 SQL Server 中),则不应在 lambda 表达式中使用方法调用。 在 .NET 公共语言运行时上下文之外,方法将没有任何意义。
一、ORM
概念:对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换,是一种解决面向对象语言和关系型数据库不匹配的技术。狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口。理想情况下,基于这样一个面向对象的接口,持久化一个OO对象应该不需要要了解任何关系型数据库存储数据的实现细节。
用ORM是为了避免写SQL语句
二、EF(Entity Framework)
从数据库中获取数据
1.在项目右键添加ADO.NET实体数据模型
2.选择从数据库生成(从数据库拿数据)
3.点新建连接,服务器名输入.,选择或输入数据库名称,测试连接,点确定
4.将App.Config中的实体连接设置另存为,这里输入一个名称
5.选中要包括的表,点完成
Entity Framework 是 ADO.NET 中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架。
//1.实例化一个数据上下文
EFDBEntities entity = new EFDBEntities();
//2.向上下文对象添加数据实体
Users users = new Users() { username="abc",password="666"};
//3.告诉上下文对象我要执行添加操作
entity.Users.Add(users);
entity.Entry(users).State = EntityState.Added;
//4.把我们对数据库的操作执行
entity.SaveChanges();
例子:
1.添加(增)
EFDBEntities entity = new EFDBEntities();
Users users = new Users() { username = "aaa", password = "111" };
entity.Entry(users).State = EntityState.Added;
entity.SaveChanges();
2.删除(删)
EFDBEntities entity = new EFDBEntities();
Users users = new Users() { id = 4 };
entity.Entry(users).State = EntityState.Deleted;
entity.SaveChanges();
3.修改(改)
EFDBEntities entity = new EFDBEntities();
Users users = new Users() { id = 4, username = "rrr", password = "333" };
entity.Entry(users).State = EntityState.Modified;
entity.SaveChanges();
4.查询(查)
//获取所有数据
var list = entity.Users;
foreach (var item in list)
{
Console.WriteLine(item.id + "---" + item.username + "---" + item.password);
}
//第一种方法,查询id=1的数据
IQueryable<Users> list1 = from u in entity.Users
where u.id == 1
select u;
//第二种方法,查询id=1的数据
IQueryable<Users> list2 = entity.Users.Where(i => i.id == 3);
//查询第一条数据
Users us = entity.Users.FirstOrDefault();
//遍历
foreach (var item in list1)
{
Console.WriteLine(item.id + "---" + item.username + "---" + item.password);
}
判断用户输入的用户名与密码是否正确:
Lambda表达式方法:
var count = db.Users.Where(d => d.Name == userName && d.Pwd == userPwd).ToList();
var count = db.Users.Count(d => d.Name == userName && d.Pwd == userPwd);//返回一个数字
Linq查询方法:
var count = (from u in db.Users where u.Name == userName && u.Pwd == userPwd select u).ToList();
生成数据库:
1.在项目右键添加ADO.NET实体数据模型
2.选择空模型,点完成
3.出来的xx.edmx关系图,在空白处右键,新增--实体
4.输入实体名称,如:Student,实体集名称一样
5.出来的框框右键---新增标量属性
6.选中属性名称,在属性中可以更改它们的属性值,如类型、是否为null
7.右键根据模型生成数据库
8.点新建连接,服务器名输入.,输入一个数据库名称,点确定,因为是新增数据库,所以测试连接是不成功的
9.最后点完成,执行操作SQL语句,便会在数据库产生一个数据库名称和表
三、Linq
//小于5,并且倒叙排列显示
int[] arr = new int[] { 8, 5, 89, 41, 1, 2, 3, 65, 1 };
var m = from n in arr where n < 5 orderby n descending select n;
//输出大小3的和
List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
//1.
var result = arr.Where(a => { return a > 3; }).Sum();
//2.
var result = (from v in arr where v > 3 select v).Sum();