用智能的编译器来防错
2016-01-29 15:46
295 查看
自动实现的属性
编写由字段直接支持的简单属性,不再显得臃肿不堪
C#2允许为取值方法指定不同的访问权限
隐式类型的局部变量
根据初始化值推断变量的类型,从而简化局部变量的声明
用var声明局部变量
使用隐式类型,唯一要做的就是将普通局部变量声明类型名称替换为var
编译器工作:获取初始化表达式在编译时的类型,并使变量也具有那种类型
变量是静态的类型,只是由编译器推断
隐式类型的限制
被声明的变量是一个局部变量,而不是一个静态字段和实例字段
变量在声明的同时被初始化
初始化表达式不是方法组也不是匿名函数
初始化表达式不是null
语句中只声明了一个变量
你希望变量拥有的类型是初始化编译时的类型
初始化表达式不包含正在声明的变量
不能这样写:varstarter=delegate(){Console.WretrLine()}
可以这样写:varstarter=(ThreadStart)delegate(){Console.WretrLine()}
同样的也适用于null
隐式类型的建议
如果代码让人一眼就能看出变量类型很重要,就使用显示类型
如果变量直接用一个构造函数初始化,而且类型名称很长,就考虑使用隐式类型
如果变量的确切类型不重要,而且它的本质在当前上下文已经很清楚,就用隐式类型,从而不去强调代码具体是如何达到目标的,而是关注它想要达到什么目标
看哪个顺眼
对象和集合的初始化程序
用一个表达式就能轻松创建初始化对象
对象初始化程序:初始化列表指定了在对象创建好后,如何对其进行初始化
设置简单属性
对象初始化程序最常用于设置属性
为嵌入对象设置属性
集合初始化程序
在其他对象初始化程序中填充集合
与对象初始化程序组合使用
初始化特性的应用
常量集合
设置单元测试
builder模式
隐式类型数组
MyMethod(new[]{"HE","EH"});
首先构造一个集合,其中包括大括号内所有的表达式的编译时的类型,在这个类型集合中,如果其他所有类型都能隐式转换为其中一种类型,改类型即为数组类型
匿名类型
投影初始化程序
编写由字段直接支持的简单属性,不再显得臃肿不堪
C#2允许为取值方法指定不同的访问权限
#region8-1统计创建了多少个实例的Person类
publicclassPerson
{
publicstringName{get;privateset;}//声明有公有取值方法的属性
publicintAge{get;privateset;}
privatestaticintInstanceCounter{get;set;}//声明私有的静态属性和锁
privatestaticreadonlyobjectcounterLock=newobject();
publicintInstanceCounterPerson(stringname,intage)
{
Name=name;
Age=age;
lock(counterLock)//访问静态属性时使用锁。应避免锁定public类型,否则实例将超出代码的控制范围
{
InstanceCounter++;
}
returnInstanceCounter;
}
}
#endregion
#region写一个有单个整数属性的结构
publicstructFoo
{
publicintValue{get;privateset;}//所有字段在被设置之前,不能使用这些属性
publicFoo(intvalue)
:this()//显示的调用无参构造函数this(),编译器才知道所有字段都被明确的赋值了
{
this.Value=value;//调用无参构造函数,改字段被设为默认值
}
}
#endregion
隐式类型的局部变量
根据初始化值推断变量的类型,从而简化局部变量的声明
用var声明局部变量
使用隐式类型,唯一要做的就是将普通局部变量声明类型名称替换为var
编译器工作:获取初始化表达式在编译时的类型,并使变量也具有那种类型
变量是静态的类型,只是由编译器推断
隐式类型的限制
被声明的变量是一个局部变量,而不是一个静态字段和实例字段
变量在声明的同时被初始化
初始化表达式不是方法组也不是匿名函数
初始化表达式不是null
语句中只声明了一个变量
你希望变量拥有的类型是初始化编译时的类型
初始化表达式不包含正在声明的变量
不能这样写:varstarter=delegate(){Console.WretrLine()}
可以这样写:varstarter=(ThreadStart)delegate(){Console.WretrLine()}
同样的也适用于null
varargss=Environment.GetCommandLineArgs();//用方法的调用结果来初始化一个变量
隐式类型的建议
如果代码让人一眼就能看出变量类型很重要,就使用显示类型
如果变量直接用一个构造函数初始化,而且类型名称很长,就考虑使用隐式类型
如果变量的确切类型不重要,而且它的本质在当前上下文已经很清楚,就用隐式类型,从而不去强调代码具体是如何达到目标的,而是关注它想要达到什么目标
看哪个顺眼
对象和集合的初始化程序
用一个表达式就能轻松创建初始化对象
对象初始化程序:初始化列表指定了在对象创建好后,如何对其进行初始化
#region8-2一个相当简单的Person类
publicclassPerson
{
publicintAge{get;set;}
publicstringName{get;set;}
List<Person>friends=newList<Person>();//对象创建时,以留空的方式创建,而不是保留空引用
publicList<Person>Friends{get{returnfriends;}}
Locationhome=newLocation();//对象创建时,以留空的方式创建,而不是保留空引用
publicLocationHome{get{returnhome;}}
publicPerson(){}
publicPerson(stringname)
{
Name=name;
}
}
publicclassLocation
{
publicstringCountry{get;set;}
publicstringTown{get;set;}
}
#endregion
设置简单属性
对象初始化程序最常用于设置属性
Persontom1=newPerson();
tom1.Name="Tom";
tom1.Age=9;
Persontom2=newPerson{Name="Tom",Age=9};//tom1在IL中
Persontom3=newPerson("Tom");
tom3.Age=9;
Personperson3=newPerson("Tom"){Age=9};//tom3在IL中
Person[]family=newPerson[]
{
newPerson{Name="Holly1",Age=36},
newPerson{Name="Holly2",Age=36},
newPerson{Name="Holly3",Age=36},
newPerson{Name="Holly4",Age=36}
};
为嵌入对象设置属性
Persontom4=newPerson("Tom");//设置一个嵌入对象属性
tom4.Age=9;
tom4.Home.Country="CS";
tom4.Home.Town="WC";
Persontom5=newPerson("Tom"){Age=9,Home={Country="CS",Town="WC"}};//设置一个嵌入对象属性
Persontom6=newPerson("Tom");//设置一个嵌入对象属性
tom6.Age=9;
tom6.Home.Country="CS";
tom6.Home.Town="WC";
集合初始化程序
#region集合初始化程序
varnames=newList<string>
{
"Holly","jon","Tom","Robin","William"
};
List<string>names1=newList<string>();//动态添加,IL中无该处代码
names1.Add("Holly1");
names1.Add("jon1");
names1.Add("Tom1");
names1.Add("Robin1");
names1.Add("William1");
Dictionary<string,int>nameAgeMap=newDictionary<string,int>//任何实现IEnumerable的类型,只要它为初始化列表中出现的每个元素提供了一个公有Add方法,就可以使用这个特性
{
{"Holly",36},//Add方法被调用3次,如果Add有多个重载版本,那么初始化列表每个不用元素都可以调用不通的重载版本
{"Jon",36},
{"Tom",9}
};
#endregion
在其他对象初始化程序中填充集合
与对象初始化程序组合使用
#region8-3使用对象1和集合初始化程序来构建一个“富对象”
Persontom=newPerson
{
Name="Tom",
Age=9,
Home={Town="WC",Country="CS"},//初始化嵌入对象
Friends=//对象初始化程序来初始化集合
{
newPerson{Name="Alberto"},
newPerson("MAx"),
newPerson{Name="Zak",Age=9},
newPerson("Ben"),
newPerson("Alice")
{
Age=9,
Home={Town="C",Country="S"}
}
}
};
#endregion
初始化特性的应用
常量集合
设置单元测试
builder模式
隐式类型数组
MyMethod(new[]{"HE","EH"});
首先构造一个集合,其中包括大括号内所有的表达式的编译时的类型,在这个类型集合中,如果其他所有类型都能隐式转换为其中一种类型,改类型即为数组类型
匿名类型
#region8-4创建具有Name和Age属性的匿名类型对象
vartom=new{Name="Tom",Age=9};//匿名对象初始化程序
Console.WriteLine("{0},{1}",tom.Name,tom.Age);//属性具有和初始化程序中的表达式一样的类型,值在创建匿名对象初始化程序中指定
#endregion
#region8-5用匿名类型填充数组,并计算总年龄
varfamily=new[]//使用隐式类型的数组初始化程序
{
new{Name="Holly",Age=36},//使用匿名对象初始化程序
new{Name="Jon",Age=32}//如果生成不同的类型,编译器无法判断声明数组的类型
};
inttotalAge=0;
foreach(varpersoninfamily)//对每个人使用隐式类型
{
totalAge+=person.Age;
}
Console.WriteLine("Totalage:{0}",totalAge);
#endregion
投影初始化程序
#region8-6从Person对象转换成一个名字和一个成年标志
List<Person>family=newList<Person>
{
newPerson{Name="Holly",Age=36},
newPerson{Name="Jon",Age=23},
newPerson{Name="Jon",Age=23}
};
varconverted=family.ConvertAll(delegate(Personperson)
{returnnew{person.Name,IsAdult=(person.Age>=18)};});//投影初始化程序:如果不指定属性名称,而只指定用于求值的表达式,它就会使用表达式最后一部分作为名称————前提是它只能是一个简单的字段和属性
foreach(varpersoninconverted)
{
Console.WriteLine("{0}isanadult?{1}",person.Name,person.IsAdult);
}
#endregion
相关文章推荐
- asp.net mvc之拦截器
- 解决不管其他元素z-index设置多高,都在视频下面的方法
- symfony路由
- 如何把图片变小
- R cannot be resolved to a variable 的解决办法
- 插入排序
- 16.使用zabbix api创建screen
- 桶排序
- 把Eclipse项目迁移到AndroidStudio
- 蓝牙的学习
- 结构及其使用 struct (C#)
- 结束C#2的讲解:最后的一些特性
- 实现迭代器的捷径
- iOS:基于Socket的第三方框架CocoaAsyncSocket的使用
- cisco sdm登录 SSH配置学习笔记
- web性能优化(项目的规范&优化)
- 简单总结修改项目中navBar和tabBar的坑
- 冒泡排序
- 胶水
- 进入快速委托通道