1. 程式人生 > >程式設計小知識之 C# indexer 和 property

程式設計小知識之 C# indexer 和 property

本文簡單介紹了混合使用 C# indexer 和 property 時可能出現的一種意外錯誤

C# 中的 property 想必大家都很熟悉,比起傳統的 get 和 set 函式, property 的一大優勢就是可以簡化程式碼:

public class PropertyClass
{
	public string Item { get; set; }
}

不過 C# 中的 indexer 可能乍看上去就有些陌生了,基本的定義方法如下:

public class IndexerClass
{
    public object this[int index] { get { return null; } set {} }
}

這種定義方式對於偏於陣列或者矩陣形式的資料型別特別有用,例如 Unity 中的 Matrix4x4 便定義了一個二維的indexer(Matrix4x4也定義了一維版本的indexer),用以提供直觀的資料訪問方式:

// indexer of UnityEngine.Matrix4x4
public float this[int row, int column]
{
	get
	{
		return this[row + column * 4];
	}
	set
	{
		this[row + column * 4] = value;
	}
}

不過令人有些意外的是,如果我們混合使用上述的 indexer 和 property,竟然會導致編譯錯誤:

// compile error ...
public class MixClass
{
	public string Item { get; set; }
	public object this[int index] { get { return null; } set {} }
}

原因在於 C# 使用了類似 property 的方式實現了 indexer,並且 indexer 所對應的 property 的變數名便是 “Item”, 所以上述程式碼會被編譯器改寫為以下形式(不準確,僅作示意):

public class MixClass
{
	public string Item { get; set; }
	public object Item { get { return null; } set {} }
}

於是同名的 property 便造成了編譯錯誤.

解決方法大概有兩種,修改 property 的名字(不要以 “Item” 命名),或者修改 indexer 的名字,其中 indexer 名字的修改需要用到屬性:

public class MixClass
{
	public string Item { get; set; }
	[System.Runtime.CompilerServices.IndexerName("IndexerItem")]
	public object this[int index] { get { return null; } set {} }
}

參考

  1. class with indexer and property named “Item”
  2. item property in c#