系列文章導航:
靜態成員和非靜態成員的區別?
const 和 static readonly 區別?
extern 是什么意思?
abstract 是什么意思?
internal 修飾符起什么作用?
sealed 修飾符是干什么的?
override 和 overload 的區別?
什么是索引指示器?
new 修飾符是起什么作用?
this 關鍵字的含義?
可以使用抽象函數重寫基類中的虛函數嗎?
C#基礎概念之密封類,屬性訪問器,接口
類和結構的區別?
C#基礎概念之抽象類,接口,接口多繼承
別名指示符是什么?
如何手工釋放資源?
C#基礎概念之P/Invoke,StringBuilder 和 String
explicit 和 implicit 的含義?
params 有什么用?
什么是反射?
16.類和結構的區別?
答:
類:
類是引用類型在堆上分配,類的實例進行賦值只是復制了引用,都指向同一段實際對象分配的內存
類有構造和析構函數
類可以繼承和被繼承
結構:
結構是值類型在棧上分配(雖然棧的訪問速度比較堆要快,但棧的資源有限放),結構的賦值將分配產生一個新的對象。
結構沒有構造函數,但可以添加。結構沒有析構函數
結構不可以繼承自另一個結構或被繼承,但和類一樣可以繼承自接口
示例:
根據以上比較,我們可以得出一些輕量級的對象最好使用結構,但數據量大或有復雜處理邏輯對象最好使用類。
如:Geoemtry(GIS 里的一個概論,在 OGC 標準里有定義) 最好使用類,而 Geometry 中點的成員最好使用結構
![](https://imageproxy.pixnet.cc/imgproxy?url=/Images/OutliningIndicators/ContractedBlock.gif&width=11&height=16)
Code
using System;
using System.Collections.Generic;
using System.Text;
namespace Example16
{
interface IPoint
{
double X
{
get;
set;
}
double Y
{
get;
set;
}
double Z
{
get;
set;
}
}
//結構也可以從接口繼承
struct Point: IPoint
{
private double x, y, z;
//結構也可以增加構造函數
public Point(double X, double Y, double Z)
{
this.x = X;
this.y = Y;
this.z = Z;
}
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return x; }
set { x = value; }
}
public double Z
{
get { return x; }
set { x = value; }
}
}
//在此簡化了點狀Geometry的設計,實際產品中還包含Project(坐標變換)等復雜操作
class PointGeometry
{
private Point value;
public PointGeometry(double X, double Y, double Z)
{
value = new Point(X, Y, Z);
}
public PointGeometry(Point value)
{
//結構的賦值將分配新的內存
this.value = value;
}
public double X
{
get { return value.X; }
set { this.value.X = value; }
}
public double Y
{
get { return value.Y; }
set { this.value.Y = value; }
}
public double Z
{
get { return value.Z; }
set { this.value.Z = value; }
}
public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
{
return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
}
public override string ToString()
{
return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
}
}
class Program
{
static void Main(string[] args)
{
Point tmpPoint = new Point(1, 2, 3);
PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
tmpPG2.X = 4;
tmpPG2.Y = 5;
tmpPG2.Z = 6;
//由于結構是值類型,tmpPG1 和 tmpPG2 的坐標并不一樣
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG2);
//由于類是引用類型,對tmpPG1坐標修改后影響到了tmpPG3
PointGeometry tmpPG3 = tmpPG1;
tmpPG1.X = 7;
tmpPG1.Y = 8;
tmpPG1.Z = 9;
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG3);
Console.ReadLine();
}
}
}
結果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9