结构struct(值类型)在实际应用要注意的二点:
.Net中的數據類型大致可以分為二類:一類是值類型,一類是引用類型;結構(struct)是值類型,從性能上考慮值類型更有優勢(關于值類型與引用類型的詳細討論不在本文范圍內,大家可以去查閱相關資料).對于一些特定場合:比如僅需要存儲數據,不需要體現具體方法的時候,建議大家用struct來代替class,但在使用過程中,有幾個容易被忽視的細節.
1.使用struct存儲數據做為數據源,與數據顯示控件綁定時:
代碼如下:
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關鍵代碼:
Code<asp:Repeater?ID="Repeater1"?runat="server">
????????<ItemTemplate>
????????????<%#?Eval("Name")?%><br/>;
????????</ItemTemplate>
????</asp:Repeater>
?
編譯時一切正常,但是運行后,報類似如下錯誤:
DataBinding:“Test._Default+MyStruct3”不包含名為“Name”的屬性
咋整?把MyStruct3的定義改成這樣:
Codepublic?struct?MyStruct3
????????{
????????????public?string?Name{set;get;}
????????????public?string?Value?{?set;?get;?}
????????}
即:我們把字段(Field)改成屬性(property),再次運行,一切OK (應該是跟<%# Eval(...)%>采用反射機制有關)
2.結構的構造函數問題
看如下代碼
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中寫的一樣,沒什么特別的,但是我們改成下面的寫法:
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的自動屬性,簡化了一下代碼,這次編譯時vs卻提示有錯:
"錯誤 在控制返回到調用程序之前,自動實現的屬性“Test._Default.MyStruct2.Value”的支持字段必須完全賦值。請考慮從構造函數初始值設定項中調用默認構造函數。?"
"在給“this”對象的所有字段賦值之前,無法使用該對象"
究其原因,我們用Reflector看下編譯器是如何處理"自動屬性"的,先把結構改成普通的類(目的是讓編譯先通過,好觀察最終生成的代碼
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;
????????}
????}
}
?
觀察一下構造函數,變成了
...
base..ctor();
this.Name = pName;
...
關鍵就在這里:對于類來講,并不要求在訪問類的實例之前對所有成員賦值,所以這里引用this是合法的;而值類型要求在使用前必須對所有成員賦值,所以值類型如果在構造函數中直接給自動屬性賦值,這里this代表的就是結構本身,而在此之前自動生成的二個私有成員private string <Name>k__BackingField和private string <Value>k__BackingField還沒賦值,因此報錯也就是合情合理了
總結
以上是生活随笔為你收集整理的结构struct(值类型)在实际应用要注意的二点:的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 视频监控系列(7):服务器端——封
- 下一篇: Livemesh文件同步功能--使用图解