有关静态属性,静态类的文章实在是太多了,大多都是介绍了它的特性,比如在什么时候初始化,不能调用实例属性等等。
但要是不分区别的乱用静态属性,只求它不会重新实例化,节省资源,可就大错特错喽。看下面一例:
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去掉吧!!!