静态属性,不要乱用

    有关静态属性,静态类的文章实在是太多了,大多都是介绍了它的特性,比如在什么时候初始化,不能调用实例属性等等。

但要是不分区别的乱用静态属性,只求它不会重新实例化,节省资源,可就大错特错喽。看下面一例:

 class Program
{
static void Main(string[] args)
{
Person person
= new Person("001", "Allan", "", 23, "软件工程师");
Person person2
= new Person("002", "Angelina", "", 23, "销售经理");
Console.WriteLine(
"{0}, {1}, {2}, {3}, {4}", person.ID, person.Name, person.Gender, person.Age, person.post.Name);
Console.WriteLine(
"{0}, {1}, {2}, {3}, {4}", person2.ID, person2.Name, person2.Gender, person2.Age, person2.post.Name);
Console.ReadKey();
}
}

class Person
{
public Person() { }
public Person(string id, string name, string gender, int age, string postName)
{
ID
= id;
Name
= name;
Gender
= gender;
Age
= age;
post.Name
= postName;
}
public string ID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }

private static Post _post = null;
public Post post
{
get
{
if (_post == null)
_post
= new Post();
return _post;
}
}
}

/// <summary>
/// 职务
/// </summary>
class Post
{
public string ID { get; set; }
public string Name { get; set; }
}

先不要忙着复制粘贴,仔细看一下,说出它的运行结果。

嗒..

嗒...

嗒....

如果你的答案是:

那这篇小记对你一点用处都没有。但是如果不是,请往下看:

注意到上面代码中黄色下划线的一行代码了吗?这里我把它设置为静态,然后我们分析整个的流程:

首先由Main入囗函数进入,执行到

Person person = new Person("001", "Allan", "", 23, "软件工程师");

然后调用Person类的构造函数

 public Person(string id, string name, string gender, int age, string postName)
{
ID
= id;
Name
= name;
Gender
= gender;
Age
= age;
post.Name
= postName;
}

执行到黄色背景时,进入

 public Post post
{
get
{
if (_post == null)
_post
= new Post();
return _post;
}
}

当然了,在进入Person时,会首先调用

private static  Post _post = null;

到此为止,还是一切正常,没什么意外。我们看看内存中是什么样子:

当执行 private static Post _post = null 时,会在专为保存静态属性的内存开出一小段区域:

程序继续向下执行,判断_post是否为空,而后执行

_post = new Post();

这时在内存中一个叫做堆的地方开出一块内存

注:地址好像不是在这个位置上,只是个表示,大家理解就好。把这个地址1000赋予_post

_post那时的null就会变为1000

程序接着向下执行

Person person2 = new Person("002", "Angelina", "", 23, "销售经理");

因为_post为静态属性,所以不会再执行

private static  Post _post = null;

当程序执行到了

public Post post
{
get
{
if (_post == null)
_post
= new Post();
return _post;
}
}

就是这里,判断_post是否为空,因为_post是静态属性,所以一直持有这个对象,不会执行_post = new Post();

而是直接返回_post.

这样的话,在构造函数里面的

post.Name = postName;

post还是指向static区域里面的那个_post,它指向了地址为1000的那个对象,所以条语句是一个修改,既是把Name由原来的"软件工程师",改为了"销售经理"。

这也就不难理解下面的语句

Console.WriteLine("{0}, {1}, {2}, {3}, {4}", person.ID, person.Name, person.Gender, person.Age, person.post.Name);
Console.WriteLine(
"{0}, {1}, {2}, {3}, {4}", person2.ID, person2.Name, person2.Gender, person2.Age, person2.post.Name);

里面的person.post.Name也为输出"销售经理"了。因为person.post和person2.person指向的是同一个区域。

所以,把static去掉吧!!!

posted on 2011-08-20 10:54  Allan GC  阅读(994)  评论(0编辑  收藏  举报

导航