zoukankan
html css js c++ java
C#2.0语法上的变化
C#
2
.0语法上的变化:
①泛型:
为什么要引入泛型?
举个例子比较好理解:例如定义一个System.Collection.ArrayList,里面的元素是object类型的,当从中取出的时候需要作强制类型转换ClassA tmp
=
myArrayList[
0
]
as
ClassA;这有两方面问题,一是强制类型转换的性能开销,二是类型安全(编译通过但是运行有可能出错)。在.net1.0中类似的情况是比较多的,引入泛型是为了较好地解决此问题。
所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。
还是看看代码吧:
class
Stack
<
T
>
{
private
T[] store;
private
int
size;
public
Stack()
//
构造函数
{
store
=
new
T[
10
]; size
=
0
;
}
public
void
Push(T tmp)
{
store[size
++
]
=
tmp;
}
public
T Pop
{
return
store[
--
size];
}
}
上面就是一个泛型的实现,在实例化的时候该类的时候我们可以这样声名
Stack
<
int
>
aaa
=
new
Stack
<
int
>
();
那么就约束了只能往这个堆栈里放int类型,例如aaa.Push(
17
);是可以的;
但是aaa.Push(
"
123
"
);编译就会不通过。
class
C
<
U,V
>
{}
class
D: C
<
string
,
int
>
{}
class
E
<
U,V
>
: C
<
U, V
>
{}
class
F
<
U,V
>
: C
<
string
,
int
>
{}
上面这些都是一些泛型的实现,这里就不一一解释了
~
泛型还可以应用于接口和委托,实际编程时还有一些实际问题。
值得一提的是下面这个例子:(where)
class
MyClass
<
S,T
>
where S: A
//
S继承自A
where T: B
//
T继承自B
{
}
②匿名方法与迭代器;
匿名方法其实没什么,对比一下下面这两段代码就明白了:
(C#
1.0
):
Button1.click
+=
new
EventHandler(Button1_Click);
private
void
Button1_Click(
object
sender,EventArgs e)
{
TextBox1.Text
=
"
123
"
;
}
有了匿名方法之后(C#
2.0
):
Button1.Click
+=
delegate
{
TextBox1.Text
=
"
123
"
;
}
关于匿名方法,老实说,偶认为只是为了可以省掉几行代码,比较方便地处理委托,属于C#编译器的“小花招”而已
然后是“迭代器”:
在没有这个东东的时候如果需要创建一个集合(可用于foreach循环),需要如此实现
Public
class
MyCollection : Ienumerable
{
public
MYEnumerator GetEnumerator()
{
return
new
MyEnumerator(
this
);
}
public
class
MyEnumerator : Ienumerator
{
public
void
Reset()
{ … }
public
bool
MoveNext()
{ … }
public
int
Current
{ … }
object
IEnumerator.Current
{
get
{ … }
}
}
}
有了“迭代器”之后,这样就可以:
public
class
Stack
<
T
>
: IEnumerable
<
T
>
{
T[] items;
int
count;
public
void
Push(T data)
{…}
public
T Pop()
{…}
public
Ienumerator
<
T
>
GetEnumerator()
{
for
(
int
I
=
count –
1
; i
>=
0
;
--
i)
{
yield
return
items[i];
}
}
比较简单,看看就能明白,有两个地方稍有点新鲜的:
1
)增加了yield关键字;
2
)使用迭代器创建倒序遍历:
Public Ienumerable
<
T
>
Bottom ToTop
{
get
{
for
(
int
I
=
0
;i
<
count; i
++>
)
{
yield
return
items[i];
}
}
}
③分部类型定义:
分部类型允许我们将一个类、结构或者接口分成几个部分,分别实现在几个不用的.cs文件中。当然,各个部分的命名空间是要相同的,访问保护修饰符也不能互相冲突。
为了实现这个东西,引入了半个关键字partial,之所以叫半个,是因为只有和class、
struct
、interface放在一起时,才有关键字的含义。
分部类型的实用意义偶倒是想到一个,就是我们有一些代码文件是通过某些工具生成的(例如用一些映射工具或者自己写的代码生成工作,去生成一些基本的实体类、数据访问类等),这些代码文件我们又不希望跟手工增加的代码放在一起,就可以分开n个部分来放。
最后来段简单代码作为例子:
partial
class
MyClass
{
public
void
test1()
{
.}
}
partial
class
MyClass
{
public
void
test2()
{
.}
}
代码可以这样写,最终编译器还是会把各个部分编译到一起的,没有实质区别。
④Nullable 泛型结构:
Nullable 泛型结构允许一个值类型具有“空值”意义,从而方便很多场合的运算,如数据库中的空字段。
int
?
a
=
null
;
if
(a
==
null
)
{
//
a如果为空,则
.;
}
else
{
//
a如果不为空,则
.;
}
空属类型实际上是一个泛型类型System.Nullable
<
T
>
。
⑤静态类:
问题真是一个比一个简单,静态类就是一个只包含静态成员的类。
例子
static
class
MyStaticClass
{
public
const
int
aaa;
public
static
void
Test1()
{
//
……
}
}
数据访问
①模型的调整:
例如在ado.net1.0里,SqlConnection、OleDbConnection等,并没有一个共同的基类,而是通过继承接口 IDbConnection实现的,现在,则有了一个基类DbConnection,这可方便了一些,我们可针对基类编写数据库访问的代码,而不用关注具体的数据库类型,有利于数据访问层与数据库的分离
~
②关于DataSet(DataTable)的优化:
首先是新的索引引擎,看看例子:
DataTable dt
=
new
DataTable();
dt.Columns.Add(
"
field1
"
);
dt.Columns.Add(
"
field2
"
);
dt.PrimaryKey
=
new
DataColumn[]
{ dt.Columns[
0
] }
;
//
这句是关键,否则验证不了
for
(
int
i
=
0
; i
<
200000
; i
++
)
dt.Rows.Add(
new
object
[]
{ i, DateTime.Now }
);
上面这段代码在.net1.1执行需要40
~
50秒; 在.net2.0中运行在10秒左右
其次是真正的二进制序列化;
将上面这个包含有20万条记录的DataTable序列化成文件:
dt.RemotingFormat
=
SerializationFormat.Binary;
//
这个在.net1.1是没有的
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf
=
new
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.FileStream fs
=
new
System.IO.FileStream(
@"
D:\test1.txt
"
, System.IO.FileMode.CreateNew);
bf.Serialize(fs, dt);
fs.Close();
.net1.1得到的是一个大小约29M的文件;.net2.0得到的是约7M的文件;用记事本打开看看就知道差别在哪里。
在使用Remoting传送DataSet或者DataTable对象的时候,这是一件好事。
最后,在ado.net2.0中,DataTable更独立了,不像过去那样特别依赖DataSet,有时候不得不把DataTable放到DataSet中仅仅是为了获得某项功能,例如ReadXML()、 WriteXMlSchema()等。
③针对MS SQL Server,特别是MS SQL Server2005所作的一些优化:
这有几方面话题,一是异步处理
System.Data.SqlClient.SqlCommand cm
=
new
SqlCommand(
"
async=true;
..
"
);
System.IAsyncResult ar
=
cm.BeginExecuteReader();
//
..
//
do other processing
System.Data.SqlClient.SqlDataReader dr
=
cm.EndExecuteReader(ar);
二是大批量数据操作的优化
System.Data.SqlClient.SqlBulkCopy bcp
=
new
SqlBulkCopy(
"
连接字符串
"
);
bcp.WriteToServer(myDataTable);
三是在ADO.NET
2
.0针对Sql Server 2005可以同时在Command对象上打开多个DataReader
查看全文
相关阅读:
Commonjs,AMD,CMD和UMD的差异
ajax中datatype的json和jsonp
bufferd对象详解
NodeJS中Buffer模块详解
Vue 定义组件模板的七种方式(一般用单文件组件更好)
vuejs 单文件组件.vue 文件
git clone 带用户名密码
去掉一组整型数组重复的值
Vue中在组件销毁时清除定时器(setInterval)
使用Nginx实现反向代理
原文地址:https://www.cnblogs.com/kokoliu/p/656260.html
最新文章
WEB学习感受
CSS 伪类 (Pseudo-classes)实例
CSS 定位 (Positioning) 实例
CSS 分类 (Classification) 实例
CSS 尺寸 (Dimension) 实例
轮廓(Outline) 实例
Javascript获取页面的各种坐标汇总
js在点击的按钮下面弹框
js实现点击按钮时显示弹框,点击按钮及弹框以外的区域时隐藏弹框
26.C# 文件系统
热门文章
25.C# 异步调用Web服务
自定义控件LengthValidator
C#将文件转成16进制码流写入数据库存起来,访问的时候再还原成PDF文件。
C# CustomValidator
C# 验证控件的使用RequiredFieldValidator&CompareValidator
C# 验证控件组
vue-cli proxyTable中跨域中pathRewrite 怎么用
【bug】vue-cli 3.0报错的解决办法
...args剩余参数用法
Javascript模块化
Copyright © 2011-2022 走看看