.net framework 2.0 概论 (framework的设计与应用 学习笔记)
Assemblys
IL Code 是CLR的核心
但CLR无法直接加载只包含IL Code的文件
IL Code必须被放置到一个Module中
Module必须被放置到一个Assembly中
Assembly就是一个类似DLL Exe的文件
就像Windows中的EXE及DLL一样,可运行的Assembly中包含着一个Module,其中包含着一个Entry Pointing(程序启动点),当CLR加载可运行的Assemlby后会由此开始运行。
Assembly 结构
Assembly实际上只是一个PE格式的文件
Assembly结构图
Module 结构图
Strong-Name Assembly
在VS 2005中,通过项目的属性页来产生签名文件,然后套用到项目产生的Assembly中.
加载 Assembly
静态加载 动态加载
动态加载 : 用Assembly.Load函数来加载Assembly.
当使用动态加载时,由于编译时期Assembly A 并未被加载,所以将无法通过编译,程序用必须以Assembly.Load函数加载该Assembly A,通过返回的Assembly对象的GetType 函数来取得Class1的Type对象,再经由Activator.CreateInstance函数来创建Class1的对象实例
Application Domain 与 Thread
在Win32时代,应用程序运行在Process的Thread中,一个Process可以创建多个Thread以及子Process.
在.net 中Process有AppDomain取代。
如此设计解决两个问题:
(1):创建Process耗时耗资源,在一个Process中创建多个 appDomain的方式,可以减少Process.
(2): 跨进程 (Cross-Process)调用,耗时,由于AppDomain在同一进程中,问题则不存在。
跨AppDomain效率仍然比较差的,当使用来自另一个AppDomain中的对象时,实际上取得的是一个Proxy对象,由Proxy对象进行中介操作,也由于要创建Proxy对象,加上所有调用都要转成消息的缘故,效率也是比较差的。所以应避免跨AppDomain调用的产生.
Applicaton Domain
process可以有多个appDomain ,每个AppDomain可以有多个 Thread对象。
一般的应用程序使用AppDomain的机会并不大,大多数的应用只是挂载事件至DomainUnload来处理当AppDomain卸载时的清除工作,或是挂载到 ProcessExit来处理应用程序退出前的清除工作哦。
Threads
CLR中的线程并不等同OS中的线程。
当使用Thread时,程序员必须注意 同步处理 问题
.net 提供了四种同步机制
Monitor
最常用最基本的同步机制。
例子:
lock(variable)
{
i=100;
}
编译器会转化成:
Monitor.Enter(variable)
try
{
i=100;
}finaly
{
Monitor.Exit(variable);
}
Attributes
标签
看看Attributes能做什么
用户定义的Attribute必须继承至System.attribute类
AttributeUsage 代表着此Attribute的使用情况
AttributeTargets 该Attribute 的适用范围,可以是类、函数、属性
Inherited 此Attribute 被贴到目标物上,目标类的子类是否继承此attribute
AllowMultipe 是否允许重复贴
在.net 2.0中,可以用Attribute .IsDefine函数来判断此类型中拥有哪些Attribute ,再使用
Attribute.GetCustomAttributes函数来取得Attribute 对象。
使用范例:
程序中创建了一个Object对象,放入两个AttrClassTest对象及一个String 对象
用 Attribute.IsDefine函数来判断该对象类型是否标记了ClassShowProcessAttribute,
然后以Attribute.GetcustomAttributes函数来取得Attribute对象。
Attribute 绑定到成员变量上
测试类:
上面的例子中展现了另一种Attribute类型的应用,其接受一个Type 参数,代表着程序员在使用此Attribue时可以指定一个自定义的Type来改变其显示的行为。
程序员也可以提供一系列的预先定义的type供用户使用,这将Attribute带往另一个复杂且高扩展性的应用面。
在下面的例子中展示
这种概念将原本由客户端处理的工作交由另一个类处理,可以有效的切割应用程序,給予较高的扩展性及明确的定位。
不过此范例不是一个良好的设计,因为其在寻找Attribute时会为每一个Attribute.Type创建一个实例。有滥用内存之嫌疑,要改善这一点,程序员可以在Attribute中定义一个静态函数,并要求传入的attribute.Type类型必须拥有一个处理的静态函数
IL Code 是CLR的核心
但CLR无法直接加载只包含IL Code的文件
IL Code必须被放置到一个Module中
Module必须被放置到一个Assembly中
Assembly就是一个类似DLL Exe的文件
就像Windows中的EXE及DLL一样,可运行的Assembly中包含着一个Module,其中包含着一个Entry Pointing(程序启动点),当CLR加载可运行的Assemlby后会由此开始运行。
Assembly 结构
Assembly实际上只是一个PE格式的文件
Assembly结构图
| PE Header |
| CLR Header |
| CLR Metadata |
| Manifest |
| Modules | Resources |
Module 结构图
| PE Header |
| Stub (这里面的数据用来加载CLR环境,CLR加载完毕后,会加载紧随其后的IL Code,并转译成Native Code 来运行,这个转译操作由JIT Compiler来运行) |
| CLR Header |
| IL Code |
Strong-Name Assembly
在VS 2005中,通过项目的属性页来产生签名文件,然后套用到项目产生的Assembly中.
加载 Assembly
静态加载 动态加载
动态加载 : 用Assembly.Load函数来加载Assembly.
当使用动态加载时,由于编译时期Assembly A 并未被加载,所以将无法通过编译,程序用必须以Assembly.Load函数加载该Assembly A,通过返回的Assembly对象的GetType 函数来取得Class1的Type对象,再经由Activator.CreateInstance函数来创建Class1的对象实例
Application Domain 与 Thread
在Win32时代,应用程序运行在Process的Thread中,一个Process可以创建多个Thread以及子Process.
在.net 中Process有AppDomain取代。
如此设计解决两个问题:
(1):创建Process耗时耗资源,在一个Process中创建多个 appDomain的方式,可以减少Process.
(2): 跨进程 (Cross-Process)调用,耗时,由于AppDomain在同一进程中,问题则不存在。
跨AppDomain效率仍然比较差的,当使用来自另一个AppDomain中的对象时,实际上取得的是一个Proxy对象,由Proxy对象进行中介操作,也由于要创建Proxy对象,加上所有调用都要转成消息的缘故,效率也是比较差的。所以应避免跨AppDomain调用的产生.
Applicaton Domain
process可以有多个appDomain ,每个AppDomain可以有多个 Thread对象。
| AssemblyLoad | 触发于AppDomain载入一个Assembly时 |
| DomainUnload | 触发于AppDomain卸载时,也就是Unload函数被调用或是该AppDomain被消灭前 |
| ProcessExit | 当默认的AppDomain被卸载时触发,多半是应用程序退出时 |
一般的应用程序使用AppDomain的机会并不大,大多数的应用只是挂载事件至DomainUnload来处理当AppDomain卸载时的清除工作,或是挂载到 ProcessExit来处理应用程序退出前的清除工作哦。
Threads
CLR中的线程并不等同OS中的线程。
当使用Thread时,程序员必须注意 同步处理 问题
.net 提供了四种同步机制
| Monitor |
| Mutex |
| ReaderWriterLock |
| Semaphore |
Monitor
最常用最基本的同步机制。
例子:
lock(variable)
{
i=100;
}
编译器会转化成:
Monitor.Enter(variable)
try
{
i=100;
}finaly
{
Monitor.Exit(variable);
}
Attributes
标签
看看Attributes能做什么
用户定义的Attribute必须继承至System.attribute类
1
using System;
2
using System.ComponentModel;
3
4
namespace AttributeFullDemo
5
{
6
[attributeUsage(AttributeTargets.Class,Inherited=false,allowMultiple=false)]
7
8
public class ClassShowProcessAttribute:Attribute
9
{
10
private bool _show=false;
11
12
public bool Show
13
{
14
get
15
{
16
return _show;
17
}
18
}
19
20
public ClassShowProcessAttribute(bool show)
21
{
22
_show=show;
23
}
24
25
[ClassShowProces(true)]
26
public class ClassA\
27
{
28
}
29
}
30
}
31
32
33
using System;2
using System.ComponentModel;3

4
namespace AttributeFullDemo5
{6
[attributeUsage(AttributeTargets.Class,Inherited=false,allowMultiple=false)]7
8
public class ClassShowProcessAttribute:Attribute9
{10
private bool _show=false;11
12
public bool Show13
{14
get15
{16
return _show;17
}18
}19
20
public ClassShowProcessAttribute(bool show)21
{22
_show=show;23
}24
25
[ClassShowProces(true)]26
public class ClassA\27
{28
}29
}30
} 31
32
33
AttributeUsage 代表着此Attribute的使用情况
AttributeTargets 该Attribute 的适用范围,可以是类、函数、属性
Inherited 此Attribute 被贴到目标物上,目标类的子类是否继承此attribute
AllowMultipe 是否允许重复贴
在.net 2.0中,可以用Attribute .IsDefine函数来判断此类型中拥有哪些Attribute ,再使用
Attribute.GetCustomAttributes函数来取得Attribute 对象。
使用范例:
1
using System;
2
3
namespace AttributeFullDemo
4
{
5
[ClassShowProcess(true)]
6
public class AttrClassTest
7
{
8
public AttrclassTest()
9
{
10
}
11
}
12
}
using System;2

3
namespace AttributeFullDemo4
{5
[ClassShowProcess(true)]6
public class AttrClassTest7
{8
public AttrclassTest()9
{10
}11
}12
}程序中创建了一个Object对象,放入两个AttrClassTest对象及一个String 对象
用 Attribute.IsDefine函数来判断该对象类型是否标记了ClassShowProcessAttribute,
然后以Attribute.GetcustomAttributes函数来取得Attribute对象。
Attribute 绑定到成员变量上
1
using System;
2
using System.componentModel;
3
using System.Reflection;
4
5
namespace attributeFullDemo
6
{
7
public interface IFieldShow
8
{
9
string Show(object o);
10
}
11
12
[AttributeUsage(AttributeTargets.Field|attributeTargets.Property,Inherited=false,AllowMultiple=false)]
13
14
public class FieldShowAttribute:Attribute
15
{
16
private bool _show=false;
17
private Type _showClass=null;
18
19
public bool Show
20
{
21
get
22
{
23
return _show;
24
}
25
}
26
27
public Type ShowClass
28
{
29
get
30
{
31
return _showClass;
32
}
33
}
34
35
public IFieldShow CreateShowInstance()
36
{
37
object o;
38
39
ConstructorInfo cinfo=_showClass.GetConstructor(new Type[]{});
40
41
o=cinfo.Invoke(null);
42
43
return (IFieldShow)o;
44
45
}
46
47
public FieldShowAttribute(bool show,Type showClass)
48
{
49
_show=show;
50
_showClass=showClass;
51
52
if(_showClass==null)
53
{
54
throw new Ecepton("must provides showClass!");
55
}
56
}
using System;2
using System.componentModel;3
using System.Reflection;4

5
namespace attributeFullDemo6
{7
public interface IFieldShow8
{9
string Show(object o);10
}11
12
[AttributeUsage(AttributeTargets.Field|attributeTargets.Property,Inherited=false,AllowMultiple=false)]13
14
public class FieldShowAttribute:Attribute15
{16
private bool _show=false;17
private Type _showClass=null;18
19
public bool Show20
{21
get22
{23
return _show;24
}25
}26
27
public Type ShowClass28
{29
get30
{31
return _showClass;32
}33
}34
35
public IFieldShow CreateShowInstance()36
{37
object o;38
39
ConstructorInfo cinfo=_showClass.GetConstructor(new Type[]{});40
41
o=cinfo.Invoke(null);42
43
return (IFieldShow)o;44
45
}46
47
public FieldShowAttribute(bool show,Type showClass)48
{49
_show=show;50
_showClass=showClass;51
52
if(_showClass==null)53
{54
throw new Ecepton("must provides showClass!");55
}56
}测试类:
1
using System;
2
using System.ComponentModel;
3
4
namespace AttributeFullDemo
5
{
6
public class StringFieldShow:IFieldShow
7
{
8
string IFieldShow.Show(object o)
9
{
10
return o.ToString();
11
}
12
13
public class AttrFieldTest
14
{
15
[FieldShow(true,typeof(StringFieldShow)]
16
17
public int _number=0;
18
19
20
public AttFieldTest()
21
{
22
}
23
}
24
}
25
}
using System;2
using System.ComponentModel;3

4
namespace AttributeFullDemo5
{6
public class StringFieldShow:IFieldShow7
{8
string IFieldShow.Show(object o)9
{10
return o.ToString();11
}12
13
public class AttrFieldTest14
{15
[FieldShow(true,typeof(StringFieldShow)]16
17
public int _number=0;18
19
20
public AttFieldTest()21
{22
}23
}24
}25
}上面的例子中展现了另一种Attribute类型的应用,其接受一个Type 参数,代表着程序员在使用此Attribue时可以指定一个自定义的Type来改变其显示的行为。
程序员也可以提供一系列的预先定义的type供用户使用,这将Attribute带往另一个复杂且高扩展性的应用面。
在下面的例子中展示
1
private static void TestField()
2
{
3
AttrFieldTest[] o=new AttrFieldTest[]{new AttrFieldTest(),new AttrFieldTest()};
4
5
o[0]._number=15;
6
o[1]._number=30;
7
8
foreach(AttrFieldTest item in o)
9
{
10
foreach(FieldInfo field in item.GetType().GetFields())
11
{
12
if(Attribute.IsDefined(field,typeof(FieldShowAttribute))) //如果定义了"FieldShowAttribute"标签
13
{
14
FieldShowattribute[] fattr=(FieldShowAttribute[])Attribute.GetCustomAttributes(field,typeof(FieldShowAttribute),false);
15
//把FieldShow Attribute类型的标签放入FieldShowAttribute数组中
16
17
if(fattr.Lenth!=0)
18
{
19
Console.WriteLine(field.Name+"="+fattr[0].CreateShowInstance().Show(field.GetValue(item)));
20
}
21
}
22
}
23
}
24
}
25
private static void TestField()2
{3
AttrFieldTest[] o=new AttrFieldTest[]{new AttrFieldTest(),new AttrFieldTest()};4
5
o[0]._number=15;6
o[1]._number=30;7
8
foreach(AttrFieldTest item in o)9
{10
foreach(FieldInfo field in item.GetType().GetFields())11
{12
if(Attribute.IsDefined(field,typeof(FieldShowAttribute))) //如果定义了"FieldShowAttribute"标签13
{14
FieldShowattribute[] fattr=(FieldShowAttribute[])Attribute.GetCustomAttributes(field,typeof(FieldShowAttribute),false);15
//把FieldShow Attribute类型的标签放入FieldShowAttribute数组中16
17
if(fattr.Lenth!=0)18
{19
Console.WriteLine(field.Name+"="+fattr[0].CreateShowInstance().Show(field.GetValue(item)));20
}21
}22
}23
}24
}25

这种概念将原本由客户端处理的工作交由另一个类处理,可以有效的切割应用程序,給予较高的扩展性及明确的定位。
不过此范例不是一个良好的设计,因为其在寻找Attribute时会为每一个Attribute.Type创建一个实例。有滥用内存之嫌疑,要改善这一点,程序员可以在Attribute中定义一个静态函数,并要求传入的attribute.Type类型必须拥有一个处理的静态函数


浙公网安备 33010602011771号