|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你所列的那些其实差不多都可以称为应用服务器(servlet应该说是一种语言更合适)net网页编程是开放的,相同的工具就会有很多公司在做,加上net网页编程已经发展了很多年了,因此这些工具就很多了。他们很多都是类似的。系列文章目次索引:《你必需晓得的.NET》
本文将先容以下内容:
- 范例的基础观点
- 值范例深切
- 援用范例深切
- 值范例与援用范例的对照及使用
[下载]:[范例示例代码]
1.弁言
值范例与援用范例的话题经由了两个回合([第八回:咀嚼范例---值范例与援用范例(上)-内存有理]和[第九回:咀嚼范例---值范例与援用范例(中)-划定规矩无边])的会商和商讨,我们就基础的了解层面来讲已差未几了,可是对这一部分的进一步掌控和更深入的了解还要持续和深化,由于我本人就在两篇公布之际,我就失掉拆卸脑壳兄的不倦引导,以后又查阅了良多的材料发明范例在.NET大概说言语基本中何其主要的内在和深度,因而关于这个话题的会商还没有中断,今后我将持续分享本人的所得与所感。
不外作为一个阶段,本文将值范例和援用范例的会商从使用示例角度来进一步做以延长,能够看做是对前两回的增补性切磋。我们从范例界说、实例创立、参数传送、范例判等、渣滓接纳等几个方面来扼要的对上两回的内容做以分析,并以必定的IL言语和内存机制来讲明,希冀进一步加深我们的了解和剖析。
2.以代码分析
上面,我们以一个典范的值范例和援用范例对照的示例来分析,其区分和本色。在分析的过程当中,我们次要以实行剖析(次要是代码正文)、内存剖析(次要是图例申明)和IL剖析(次要是IL代码简析)三个方面来逐常识点剖析,最初再做以总结形貌,如许就能够有更深的了解。
2.1范例界说
界说复杂的值范例MyStruct和援用范例MyClass,在前面的示例中将渐渐完美,完全的代码能够点击下载[范例示例代码]。我们的会商如今入手下手,
//01界说值范例
publicstructMyStruct
{
privateint_myNo;
publicintMyNo
{
get{return_myNo;}
set{_myNo=value;}
}
publicMyStruct(intmyNo)
{
_myNo=myNo;
}
publicvoidShowNo()
{
Console.WriteLine(_myNo);
}
}//02界说援用范例
publicclassMyClass
{
privateint_myNo;
publicintMyNo
{
get{return_myNo;}
set{_myNo=value;}
}
publicMyClass()
{
_myNo=0;
}
publicMyClass(intmyNo)
{
_myNo=myNo;
}
publicvoidShowNo()
{
Console.WriteLine(_myNo);
}
}
<br>
剖析IL代码可知,静态办法.ctor用来暗示完成机关办法的界说,个中该段IL代码暗示将0赋给字段_myNo。
2.2创立实例、初始化及赋值
接上去,我们完成实例创立和初始化,和复杂的赋值操纵,然后在内存和IL剖析中发明实在质。
<br>
<br>创立实例、初始化及赋值
publicstaticvoidMain(string[]args)
{
//内存分派于线程的仓库上
//创立了值为等价"0"的实例
MyStructmyStruct=newMyStruct();
//在线程的仓库上创立了援用,但未指向任何实例
MyClassmyClass;
//内存分派于托管堆上
myClass=newMyClass();
//在仓库上修正成员
myStruct.MyNo=1;
//将指针指向托管堆
myClass.MyNo=2;
myStruct.ShowNo();
myClass.ShowNo();
//在仓库上新建内存,并实行成员拷贝
MyStructmyStruct2=myStruct;
//拷贝援用地点
MyClassmyClass2=myClass;
//在仓库上修正myStruct成员
myStruct.MyNo=3;
//在托管堆上修正成员
myClass.MyNo=4;
myStruct.ShowNo();
myClass.ShowNo();
myStruct2.ShowNo();
myClass2.ShowNo();
}
起首是值范例和援用范例的界说,这是统统面向对象的入手下手,
<br>
然后是初始化历程,
<br>
复杂的赋值和拷贝,是最基础的内存操纵,无妨看看,
<br>
2.3参数传送
参数传送
//04ref和out
publicclassRefAndOut
{
publicstaticvoidMain()
{
//必需举行初始化,才干利用ref体例传送
intx=10;
ValueWithRef(refx);
Console.WriteLine(x);
//利用out体例传送,不用初始化
inty;
ValueWithOut(outy);
Console.WriteLine(y);
objectoRef=newobject();
RefWithRef(refoRef);
Console.WriteLine(oRef.ToString());
objectowith;
RefWithOut(outowith);
Console.WriteLine(owith.ToString());
}
staticvoidValueWithRef(refinti)
{
i=100;
Console.WriteLine(i.ToString());
}
staticvoidValueWithOut(outinti)
{
i=200;
Console.WriteLine(i.ToString());
}
staticvoidRefWithRef(refobjecto)
{
o=newMyStruct();
Console.WriteLine(o.ToString());
}
staticvoidRefWithOut(outobjecto)
{
o=newString("a",10);
Console.WriteLine(o.ToString());
}
}
不用多说,就是一个扼要阐释,关于参数的传送作者将企图以更多的文字来在前面的系列中做以廓清和深切。
2.4范例转换
范例转换的演示,包含良多个方面,在此我们只以自界说范例转换为例来做以申明,更具体的范例转换能够参考[第九回:咀嚼范例---值范例与援用范例(中)-划定规矩无边]的[再论范例转换部分]。
起首是值范例的自界说范例转换,
publicstructMyStruct
{
//01.2自界说范例转:整形->MyStruct型
staticpublicexplicitoperatorMyStruct(intmyNo)
{
returnnewMyStruct(myNo);
}
}
然后是援用范例的自界说范例转换,
publicclassMyClass
{
//02.2自界说范例转换:MyClass->string型
staticpublicimplicitoperatorstring(MyClassmc)
{
returnmc.ToString();
}
publicoverridestringToString()
{
return_myNo.ToString();
}
}
最初,我们对自界说的范例做以测试,
publicstaticvoidMain(string[]args)
{
#region03.范例转换
MyStructMyNum;
inti=100;
MyNum=(MyStruct)i;
Console.WriteLine("整形显式转换为MyStruct型---");
Console.WriteLine(i);
MyClassMyCls=newMyClass(200);
stringstr=MyCls;
Console.WriteLine("MyClass型隐式转换为string型---");
Console.WriteLine(str);
#endregion
}
2.5范例判等
范例判等次要包含:ReferenceEquals()、Equals()虚办法和静态办法、==操纵符等方面,同时注重在值范例和援用范例判等时的分歧的地方,能够参考[第九回:咀嚼范例---值范例与援用范例(中)-划定规矩无边]的[4.再论范例判等]的简述。
//01界说值范例
publicstructMyStruct
{
//01.1值范例的范例判等
publicoverrideboolEquals(objectobj)
{
returnbase.Equals(obj);
}
}
publicclassMyClass
{
//02.1援用范例的范例判等
publicoverrideboolEquals(objectobj)
{
returnbase.Equals(obj);
}
}
publicstaticvoidMain(string[]args)
{
#region05范例判等
Console.WriteLine("范例判等---");
//05.1ReferenceEquals判等
//值范例老是前往false,经由两次装箱的myStruct不成能指向统一地点
Console.WriteLine(ReferenceEquals(myStruct,myStruct));
//统一援用范例对象,将指向一样的内存地点
Console.WriteLine(ReferenceEquals(myClass,myClass));
//RefenceEquals以为null即是null,因而前往true
Console.WriteLine(ReferenceEquals(null,null));
//05.2Equals判等
//重载的值范例判等办法,成员巨细分歧
Console.WriteLine(myStruct.Equals(myStruct2));
//重载的援用范例判等办法,指向援用不异
Console.WriteLine(myClass.Equals(myClass2));
#endregion
}
2.6渣滓接纳
起首,渣滓接纳机制,相对不是一言半语就可以交卸分明,剖析分明的。因而,本示例只是从最复杂的申明动身,对渣滓接纳机制做以复杂的剖析,目标是善始善终的交卸实例由创立到灭亡的全历程。
publicstaticvoidMain(string[]args)
{
#region06渣滓接纳的复杂阐释
//实例界说及初始化
MyClassmc1=newMyClass();
//声明但不实体化
MyClassmc2;
//拷贝援用,mc2和mc1指向统一托管地点
mc2=mc1;
//界说另外一实例,并完成初始化
MyClassmc3=newMyClass();
//援用拷贝,mc1、mc2指向了新的托管地点
//那末本来的地点成为GC接纳的对象,在
mc1=mc3;
mc2=mc3;
#endregion
}
<br>
GC实行时,会遍历一切的托管堆对象,依照必定的递回遍历算法找出一切的可达对象和不成会见对象,明显本示例中的托管堆A对象没有被任何援用会见,属于不成会见对象,将被列进实行渣滓搜集的方针。对象由newobj指令发生,到被GC接纳是一个庞大的历程,我们希冀在系列的前期对此做以深切浅出的了解。
2.7总结报告
这些示例次要从从基本的偏向动手来分析前前两回中的切磋,不求可以周全而深奥,但求可以一点而及面的睁开,手艺的魅力正在于一成不变,手艺寻求者的力图倒是从变更中追求稳定,否则我们本色太累了,我想这就是好办法,本系列但愿的就是供应一个出口,翻开一个办法。示例的具体剖析能够下载[范例示例代码],复杂的剖析但愿能带来丝丝满意。
3.结论
值范例和援用范例,要说的,要做的,另有良多。此篇只是一个阶段,更多的深切和切磋我信任还在持续,同时普遍的存眷手艺力气的发展,是每一个人应当朝上进步的空间和路途。
咀嚼范例,为使用之路启示手艺基本。
咀嚼范例,持续切磋还会更多出色。
参考文献
(USA)JeffreyRichter,AppliedMicrosoft.NETFrameworkProgramming
(USA)JacquieBarker,GrantPalmer,BeginningC#ObjectsFromConceptstoCode
广而告之
[下载]:[范例示例代码]
|
|