结构struct(值类型)在实际应用要注意的二点:
.Net中的數(shù)據(jù)類(lèi)型大致可以分為二類(lèi):一類(lèi)是值類(lèi)型,一類(lèi)是引用類(lèi)型;結(jié)構(gòu)(struct)是值類(lèi)型,從性能上考慮值類(lèi)型更有優(yōu)勢(shì)(關(guān)于值類(lèi)型與引用類(lèi)型的詳細(xì)討論不在本文范圍內(nèi),大家可以去查閱相關(guān)資料).對(duì)于一些特定場(chǎng)合:比如僅需要存儲(chǔ)數(shù)據(jù),不需要體現(xiàn)具體方法的時(shí)候,建議大家用struct來(lái)代替class,但在使用過(guò)程中,有幾個(gè)容易被忽視的細(xì)節(jié).
1.使用struct存儲(chǔ)數(shù)據(jù)做為數(shù)據(jù)源,與數(shù)據(jù)顯示控件綁定時(shí):
代碼如下:
Codeprotected?void?Page_Load(object?sender,?EventArgs?e)
????????{
????????????List<MyStruct3>?_list?=?new?List<MyStruct3>();
????????????_list.Add(new?MyStruct3()?{?Name?=?"abc",?Value?=?"123"?});
????????????_list.Add(new?MyStruct3()?{?Name?=?"cde",?Value?=?"345"?});
????????????this.Repeater1.DataSource?=?_list;
????????????this.Repeater1.DataBind();
????????????
????????}
?public?struct?MyStruct3
????????{
????????????public?string?Name;
????????????public?string?Value;
????????}
?
前端aspx關(guān)鍵代碼:
Code<asp:Repeater?ID="Repeater1"?runat="server">
????????<ItemTemplate>
????????????<%#?Eval("Name")?%><br/>;
????????</ItemTemplate>
????</asp:Repeater>
?
編譯時(shí)一切正常,但是運(yùn)行后,報(bào)類(lèi)似如下錯(cuò)誤:
DataBinding:“Test._Default+MyStruct3”不包含名為“Name”的屬性
咋整?把MyStruct3的定義改成這樣:
Codepublic?struct?MyStruct3
????????{
????????????public?string?Name{set;get;}
????????????public?string?Value?{?set;?get;?}
????????}
即:我們把字段(Field)改成屬性(property),再次運(yùn)行,一切OK (應(yīng)該是跟<%# Eval(...)%>采用反射機(jī)制有關(guān))
2.結(jié)構(gòu)的構(gòu)造函數(shù)問(wèn)題
看如下代碼
Codepublic?struct?MyStruct?{
????????????private?string?_name;
????????????private?string?_value;
????????????public?string?Name?{
????????????????set?{?_name?=?value;?}
????????????????get?{?return?_name;?}
????????????}
????????????public?string?Value
????????????{
????????????????set?{?_value?=?value;?}
????????????????get?{?return?_value;?}
????????????}
????????????public?MyStruct(string?pName,?string?pValue)?
????????????{
????????????????_name?=?pName;
????????????????_value?=?pValue;
????????????}
????????}
?
一切跟在Class中寫(xiě)的一樣,沒(méi)什么特別的,但是我們改成下面的寫(xiě)法:
Codepublic?struct?MyStruct
????????{
????????????public?string?Name?{?set;?get;?}
????????????public?string?Value?{?set;?get;?}
????????????public?MyStruct(string?pName,?string?pValue)?
????????????{
????????????????Name?=?pName;
????????????????Value?=?pValue;???????????????
????????????}
????????}
即利用c#3.0的自動(dòng)屬性,簡(jiǎn)化了一下代碼,這次編譯時(shí)vs卻提示有錯(cuò):
"錯(cuò)誤 在控制返回到調(diào)用程序之前,自動(dòng)實(shí)現(xiàn)的屬性“Test._Default.MyStruct2.Value”的支持字段必須完全賦值。請(qǐng)考慮從構(gòu)造函數(shù)初始值設(shè)定項(xiàng)中調(diào)用默認(rèn)構(gòu)造函數(shù)。?"
"在給“this”對(duì)象的所有字段賦值之前,無(wú)法使用該對(duì)象"
究其原因,我們用Reflector看下編譯器是如何處理"自動(dòng)屬性"的,先把結(jié)構(gòu)改成普通的類(lèi)(目的是讓編譯先通過(guò),好觀(guān)察最終生成的代碼
Code?public?class?MyClass
????????{
????????????public?string?Name{set;get;}
????????????public?string?Value?{?set;?get;?}
????????????public?MyClass(string?pName,?string?pValue)?
????????????{
????????????????Name?=?pName;
????????????????Value?=?pValue;
????????????}
????????}
用Reflector反編譯成C# 1.0后,代碼如下:
Codepublic?class?MyClass
{
????//?Fields
????[CompilerGenerated]
????private?string?<Name>k__BackingField;
????[CompilerGenerated]
????private?string?<Value>k__BackingField;
????//?Methods
????public?MyClass(string?pName,?string?pValue)
????{
????????base..ctor();
????????this.Name?=?pName;
????????this.Value?=?pValue;
????????return;
????}
????//?Properties
????public?string?Name
????{
????????[CompilerGenerated]
????????get
????????{
????????????string?str;
????????????str?=?this.<Name>k__BackingField;
????????Label_0009:
????????????return?str;
????????}
????????[CompilerGenerated]
????????set
????????{
????????????this.<Name>k__BackingField?=?value;
????????????return;
????????}
????}
????public?string?Value
????{
????????[CompilerGenerated]
????????get
????????{
????????????string?str;
????????????str?=?this.<Value>k__BackingField;
????????Label_0009:
????????????return?str;
????????}
????????[CompilerGenerated]
????????set
????????{
????????????this.<Value>k__BackingField?=?value;
????????????return;
????????}
????}
}
?
觀(guān)察一下構(gòu)造函數(shù),變成了
...
base..ctor();
this.Name = pName;
...
關(guān)鍵就在這里:對(duì)于類(lèi)來(lái)講,并不要求在訪(fǎng)問(wèn)類(lèi)的實(shí)例之前對(duì)所有成員賦值,所以這里引用this是合法的;而值類(lèi)型要求在使用前必須對(duì)所有成員賦值,所以值類(lèi)型如果在構(gòu)造函數(shù)中直接給自動(dòng)屬性賦值,這里this代表的就是結(jié)構(gòu)本身,而在此之前自動(dòng)生成的二個(gè)私有成員private string <Name>k__BackingField和private string <Value>k__BackingField還沒(méi)賦值,因此報(bào)錯(cuò)也就是合情合理了
總結(jié)
以上是生活随笔為你收集整理的结构struct(值类型)在实际应用要注意的二点:的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C# 视频监控系列(7):服务器端——封
- 下一篇: Livemesh文件同步功能--使用图解