为了提高代码的执行效率,我们经常采用对象静态化的方法。但是在使用静态对象的时候,特别是一个公共类, 类名为TestClass:
1、程序员A需要一个静态对象,于是在公共类中添加了一句代码public StaticObjectA A = new StaticObjectA();
2、程序员B需要一个静态对象,于是在公共类中添加了一句代码public StaticObjectB B = new StaticObjectB();
....
N、程序员N需要一个静态对象,于是在公共类中添加了一句代码public StaticObjectN N= new StaticObjectN);
1
public
TestClass
2
{
3
public
static
StaticObjectA A
=
new
StaticObjectA();
4
public
static
StaticObjectB B
=
new
StaticObjectB();
5
//
.....
6
public
static
StaticObjectN N
=
new
StaticObjectN();
7
}
看起来视乎大家都得到了自己想要的东西,其实TestClass被编译以后的代码会被修改成如下情况:
public
TestClass
{
static
StaticObjectA A;
static
StaticObjectB B;
//
.....
static
StaticObjectN N;
static
TestClass()
{
A
=
new
StaticObjectA();
B
=
new
StaticObjectB();
//
.....
C
=
new
StaticObjectN();
}
}
代码被编译后,所有的静态对象的初始化都被移到了静态构造函数中,因为静态对象都是在对象第一次被使用的时候被初始化,也就是对象在第一次调用时,都会先执行该对象的静态构造函数(除非该类内部无静态对象)。
试想如果在对象StaticObjectA的初始化过程中,需要调用对象StaticObjectB,会发生什么情况?如果你不仔细分析的话,肯定会觉得这个问题很不可思议,因为静态对象是不需要初始化的,为何还会出现在调用的时候报“未将对象引用设置到对象的实例“这样的错误。
其实这个错误就是由于静态对象的初始化顺序导致的,在使用对象StaticObjectB的时候,该对象还未被初始化。如果这个公共类被几个人使用的话,就很有可能出现这样的问题,那么如何避免这样的问题呢?
这里提出一种方法(当然如果你对每一个对象的初始化都了如指掌,然后调整好每一个对象的顺序就可以不需要我这里提出的这种方法了):静态属性。这里直接贴代码。
public
TestClass
{
static StaticObjectA _A;
public static StaticObjectA A
{
if(_A == null)
{
_A = new StaticObjectA();
}
return _A;
}
static StaticObjectB _B;
public static StaticObjectB B
{
if(_B == null)
{
_B = new StaticObjectB();
}
return _B;
}
//
.....
static StaticObjectN _N;
public static StaticObjectN N
{
if(_N == null)
{
_N = new StaticObjectN();
}
return _N;
}
}
使用静态属性的优点有如下几点:
1、类内部的对象的初始化被延迟了。也就是说TestClass对象在被第一次调用的时候,不需要执行该对象的静态构造函数了。
2、对象第一次被调用是的速度加快了。该优点由1衍生而来,由于不需要调用静态构造函数,省去里所有静态对象的初始化,当然第一次调用的时候速度会快一些。
3、暂时我还不知道,欢迎提出!
使用静态属性的缺点有如下几点:
1、每一个静态对象都要定义两次,一个是对外公共的,一个是私有的。
2、暂时我还不知道、欢迎提出!
综合以上内容,所有我建议使用静态属性,不知道大家有上面看法,欢迎指点!
下面为题外话
其实不管是非静态属性对象还是静态属性对象都会面临一个问题,那就是同一个属性对象在内存中会出现两个引用。
比如我们有这么一个类:
public
class
TestClass
{
public
string
StringValue1 {
get
;
set
; }
public
static
string
StringValue2 {
get
;
set
; }
}
看起来两行代码的类,其实被编译后会变成下面的代码:
public
class
TestClass
{
//
Fields
[CompilerGenerated]
private
string
<
StringValue1
>
k__BackingField;
[CompilerGenerated]
private
static
string
<
StringValue2
>
k__BackingField;
//
Properties
public
string
StringValue1
{
[CompilerGenerated]
get
{
return
this
.
<
StringValue1
>
k__BackingField;
}
[CompilerGenerated]
set
{
this
.
<
StringValue1
>
k__BackingField
=
value;
}
}
public
static
string
StringValue2
{
[CompilerGenerated]
get
{
return
<
StringValue2
>
k__BackingField;
}
[CompilerGenerated]
set
{
<
StringValue2
>
k__BackingField
=
value;
}
}
}
ASP.NET开发技术交流群: 67511751(人员招募中...)