跟下划线拜拜
在visualstudio.NET中引入了对C扩展名的处理,扩展名是以两个下划线开始的关键字,比如__gc和__property.自从上个版本发布以来,我已经写了大量的双下划线特征的代码,我坦白也不喜欢这样,我了解具体的原因是:带两个下划线的关键字作为特殊的扩展名使它们不会跟标准编译器相混淆,你可以全面的管理扩展名可以用其他的编译器来编译,它忽视__关键字。
这是一种解决方法:微软发现了一种方法不改变编程语言的改变,但是会出现下面一些结果:
·开发者发现语法不自然
·不能被完全的采用
如例,适当的C处理方法:
public__gcclassFoo
{
//hundredsoflinesofcode
__propertyString*get_Text();
//hundredsoflinesofcode
__propertyvoidset_Text(String*);
//hundredsoflinesofcode
};
财软 联盟 fs119.net
财 软联盟 fs119.net
财管.家园.fs119.net
财.软联盟.fs119.net 生存时间和范围
我喜欢确定的解析,实际上我也喜欢碎片收集,我还能举出更多的,它们有自己的作用而且我也需要它们,假如我只在内存中构造一个对象,我希望在我自己清除它前不被清除,
所以内存管理是很复杂的。但是,如果你的对象包含一个非管理的源文件如数据库链接,一个开放文件,或者类似我要取得一个控制。我想知道它要尽快的离开,用这种模式去处理,但是它不是直接的,简单的亲密支持是最好的办法。
下面是在原始的C中,你去完成这些事情:
//thisisacodefragment
{
try
{
Foo*f=newFoo(/*params*/);
//allkindsofcode,someofwhichmightthrowexceptions
deletef;
}
catch(/*something*/)
{
deletef;
//whateverelse,orrethrow;
}
}
如果你在堆栈建立对象,生命期是简单的 财软联.盟.fs119.net
//thisisacodefragment
{
Foof;
//allkindsofcode,someofwhichmightthrowexceptions
}
当f超过范围,不论是否是意外它将被清除这是自然的。
当对象在管理堆里时,你不能把它删除,它将被碎片收集清除,如果你想清除管理着源文件的对象,你可以调用dispose()函数,虽然C#为它提供了的有效的结构,但是它仍然不象堆栈那样简单。
在新一代的语言(以前是C/CLI),你在哪里建立对象不依赖于你建立对象的种类,你可以堆栈中管理对象,它有确定的解析,但它越界时将被清除,如果你愿意你可以在管理堆里建立对象。
这种变化带来其它的结果,其中最深远的是你可以把不同的对象放在摸板中或者可以把它看成其它类的成员变量,你可以得到完整的C生存时间周期,而不是仅仅是把它分配到相应的堆,然后等碎片收集来处理它。 财管家园 fs119.net
解析和定稿
当你为其它语言写了碎片收集对象是,你是否为它写了解析函数?当你使用C,你可以在堆栈构造对象,解析函数将运行当它越界时,什么事情会发生当其他C#或VB程序调用这个对象,运行时仅从简单的方式去处理,它是用dispose()来解析,任何一个C/CLI对象都有一个可以任意调用的解析函数。
假如你在C#或VB中有dispose()的类,你可能已经写了一个定论,C/CLI也有简便的语法为定论,就象Foo的解析是~Foo,Foo的定论是!Foo(~是比特的not,!是逻辑的not,它们都是提醒是和构造函数对立的),
Finalizer将运行当在管理堆中建立而不被调用,确信它所包含的非管理源文件被清除,即使其他调用函数忘了去解析。
指针和句柄
在C扩展名管理中,C的主要限制没有变化,同样的符号和语法用做完全的事情,*的含义依赖于你的代码中的其他位置的信息,你可以试试下面的代码:
Foo对象将在哪里建立?那块内存是否被清除?我能象下面那样对指针做算法吗:
pf;
答案依赖于Foo是否用__gc关键字声明,假如它是碎片收集对象,它只能在管理堆不是在本堆和堆栈中建立,另一方面,如果没有用__gc声明,将在本堆中分配内存给它,你必须记得去清除它。
如果编译器有自由去改变语言,就象在C/CLI上发生的,可以忽视什么地方生存的什么类型的类,可以用不同的语法表明它在哪里生存:
这被叫做句柄,许多C团队好象都是用^符号来标明的,你可以用*和->来解除句柄的引用,你可以从实例的声明而不是回过头从类的声明中得到生命期的声明。例如:
refclassR
{
private:
intm_a;
public:
R(inta):m_a(a){}
};