我怎么看你都是知道的?构造函数就是为了初始化对象用的,里面要执行什么方法自己写,随意(也可以在初始化的时候就销毁对象,以表示自己有病)。至于静态构造函数和JAVA的静态块还是有区别的,JAVA的静态块是一定会在程序开始的时候执行的,而C#的静态构造函数则不一定,必须是第一次用到那个类的时候才会被执行,否则一直不会被执行,触发的时机不一样。
请问如何做到在构造函数里就销毁对象?
@水牛刀刀: 继承IDispose接口,并在构造函数中调用Dispose方法。只不过内存的释放和这个无关,完全由GC在管理。
JAVA的静态块是一定会在程序开始的时候执行的
静态块也是只执行一次的啊。
@林J: 我没说静态块不是只执行一次啊,我只是说执行的时机不一样,Java的静态块肯定会执行一次,而且是在程序执行的最初就被执行了,优先于所有非静态块的执行。但是C#不同,必须是某个代码里面用到了那个类才会执行类中的静态构造函数,虽然只会被执行一次,但如果那个类迟迟未被调用,或者一直不被用到(某个按钮事件里面,但按钮从未被点击),那么就永远不会执行那个静态构造函数了。
@青龙白虎: 原来是这样,明白了。谢谢。
@林J: 我在JAVA下调试了一下,结果发现不实例化类的话,静态块也是不执行的。囧。
@林J: 我想起来了,Java所有的方法都必须在类中执行,静态块必须属于某个类。因为Java很少使用,在比较的时候把静态块定义想到类外部去了。囧。
不过C#的部分解释没问题的,你可以放心,我对C#的研究非常深入,甚至会直接使用IL写中间语言。
楼主,你可以看下那个clr via c#的书,看了以后,你肯定有很大的收获
我是在看书,就是看书才发现了问题。很多书内讲了原理,却不讲动机,我知道这么做能完成什么功能,但不知道为什么要这么做,不这么做又会怎么样。
你先去深入学习下面向对象再来讨论构造函数、析构函数的必要性。
如果我有问题不提出来,不拿来讨论,我又怎么能深入研究?
@林J: 这样你写一段代码来证明构造函数无用,然后我来针对你的代码给你举反例。估计这样你才能够明白。
@Launcher: 水牛刀刀那一楼的例子正是我所疑惑的地方,不过现在我觉得那已经不是重点所在了。
现在个人理解构造函数最大的用处是体现在有参数的实例化的情况下。
@林J: 按照面向对象的观点,类的实例是有生存周期,既然有生命周期,那么就有生,有死。生的过程由构造函数完成,死的过程由析构函数完成。编译器通过的构造函数执行完毕来确定一个对象的实例是可用的,同时通过调用析构函数来标识对象的实例不再可用。如果类包含一些私有资源需要在可用前分配,在不再可用前释放,那么构造函数和析构函数的配合工作就能够保证资源的分配和释放的代码在正确的位置执行,同时也保证这些代码被复用,这样就满足了面向对象的封装原则。通过继承,子类可以继承父类的构造和析构。
对于水牛刀刀那一楼的例子,你可以再复习一下在有GC的环境中,对象的析构是如何完成的:http://zhidao.baidu.com/question/172960970.html
同时,在有GC的环境中,弱引用的概念,你也应该了解下。
如果要明白构造函数和析构函数的作用,不需要去理解C#,JAVA的垃圾回收机制,而应该从继承、封装、多态三大特征,以及开放封闭原则、Liskov替换原则等来理解构造和析构的必要性。
@Launcher: 长知识了,因为C#得有自动内存管理机制,对于涉及内存的概念都是直接跳过的,看来真应该更系统地学习一下。
构造函数是一种特殊的方法,主要是为了给初始化对象赋初值。但是我可以直接在初始化时就赋值啊。
构造函数可以包含参数,构造函数包含的参数给调用者提出要求:这些参数,是创建这个类必须要用的。这比你直接在初始化的时候赋值更灵活,也更规范。
C#里的静态构造函数和JAVA里的静态块应该是一个概念
我对java的静态块了解的不是很深入,就我看来效果差不多。C#的静态构造函数在这个类第一次被使用的时候执行一次,并且只会执行一次。
谢谢你的回答,你的第一条回答正是我刚刚和别人讨论得出的结果,但刚刚我还不太确定。我一开始一直纠结于默认构造函数的用处,在这上面绕了圈子。
@林J: 就算是默认构造函数,效果也不同。我给你举个例子:
class User { public string CreateTime { get; private set; } public User() { this.CreateTime = DateTime.Now; } }
这个简单的例子作用是当new User()的时候自动生成了CreateTime。在语言层面,你完全可以没有任何构造函数,然后这么做:
var user = new User(); user.CreateTime = DateTime.Now;
这样产生的user对象是一样的。但是从设计方面,后一种做法把CreateTime的赋值工作交给了调用者,这样的程序就依赖“调用者的素质”,比如,调用者不知道要给这个字段赋值,或者胡乱赋值,等等。因此是很不同的。
@林J: 如果你只是纠结默认的构造函数是否有意义,有时它的确不执行任何代码,仅仅是作为必须的一个存在,这是语言规范,初始化类的对象时必须执行一个构造函数,没有的话就执行默认构造函数,而不管构造函数本身是否执行了什么动作。因此在写代码的时候,可以不写任何构造函数,系统会创建一个空的默认构造函数帮助你简化代码,感觉不到任意异常的存在,不知道你又是如何把这种异常感觉出来的。
@水牛刀刀: 这里正是我当初绕圈的地方 因为构造函数所完成的这个功能,完全可以在给CreateTime 初始化的时候就完成 比方说
public string createTime = DateTime.Now.ToString(); public string CreateTime { get { return this.createTime; } set { this.createTime = value; } } } public class ProgramTest { static void Main(string[] args) { User t1 = new User(); Console.WriteLine(t1.CreateTime); Console.Read(); } }
所以我会觉得构造函数并不是必须的。
@青龙白虎: 我以前学C#学的很笼统,很多东西会用,但是不知道为什么要这么用。今天准备从头开始系统地学习一下,下了两本PDF慢慢看过来,这当中发现了一些问题。并不是感觉到有异常,只是不知道有些东西设计的初衷是什么。这应该是我实践还比较少的关系,感触不深。 感谢你的回答!
@林J: .... 这哥们怎么跑到我的答案里去回答你,你别理他,他都是胡说八道。
C#里的静态构造函数和JAVA里的静态块应该是一个概念