泛型是程式語言的一種特性。允許開發者在強型別程式語言中編寫代碼時定義一些可變部份,那些部份在使用前必須作出指明。各種程式語言和其編譯器、執行環境對泛型的支援均不一樣。
集合是將密切關聯的資料放在同一個集合中,可以更有效率地來處理這些資料。不需撰寫個別程式碼來處理各個別物件,您可以另行使用相同程式碼以處理集合的所有元素。
一般型別 | 泛型型別 |
ArrayList | List< > |
Queue | Queue< > |
Stack | Stack< > |
Hashtable | Dictionary< > |
StoredList | StoredList< > |
ListDictionary | Dictionary< > |
HybridDictionary | Dictionary< > |
OrderedDictionary | Dictionary< > |
SortedDictionary | StoredDictionary< > |
NameValueCollection | Dictionary< > |
DictionaryEntry | KeyValPair< > |
StringCollection | List<String> |
StringDictionary | Dictionary<String> |
表格左邊一般型別,右邊則是對應的泛型型別,功能就跟一般型別差不多,使是用法不同罷了。假設當你需要撰寫一個功能/類別時,而無得知使用者會使用什麼型態的參數,有可能是string、也有可能是int,用泛型就不用擔心程式被呼叫時還要考慮傳入的型別,只要專心開發功能即可。
標準的集合,在功能上或執行的效率都有限制,System.Collections 命名空間
Hashtable | 用於包含10個或更多項目的集合,對小集合沒效率。 |
SortedList | 依索引鍵來排序項目。 |
集合類別結構
DictionaryEntry | 主要是用來取出字典集合著Key和Value,可以利用它來逐一處理集合中的項目。 |
集合類別介面
IDictionary | 主要是用索引鍵來存取項目,不能用索引值。 |
IComparer | 自訂排序與順序的比較 |
IEqualityComparer | 只接受相等比較,自訂排序與順序的比較是由 IComparer 介面來提供 |
比較集合
CaseInsensitiveComparer | 比較兩個物件是否相等,忽略字串的大小寫。 |
特殊的集合,彌補標準字典的限制,System.Collections.Specialized 命名空間
ListDictionary | 用於包含10個或更少項目的集合,對大集合沒效率。 |
HybridDictionary | 會先實作成ListDictionary的小集合,當內部變大時,將會把自己變成Hashtable的大集合。 |
OrderedDictionary | 比SortedList類別多了一些功能,更為強大。 |
字串集合,只能使用字串,如果操作的對象不是物件而是字串,那這個類別是首選,因為它可以省下轉型的動作
StringDictionary | 索引鍵與資料值均採用強式型別宣告為字串,用法跟Hashtable相似 |
StringCollection | 用法跟ArrayList相似 |
NameValueCollection | 與StringDictionary相似,差別在於NameValueCollection可以單一索引鍵對應多重值。 |
CollectionsUtil | 建立忽略字串大小寫Hashtable與SortedList的集合。 |
如何使用泛型型別,以下就以List< >類別來做說明
1.匯入命名空間 System.Collections.Generic
using System.Collections.Generic;
2.引用泛型類別
List<string> myGen = new List<string>();
3.加入集合
myGen.Add("簡單");
myGen.Add("範例");
4.輸出
foreach (string i in myGen)
{
Console.WriteLine(i);
}
泛型並不困難,使用上跟一般型別沒什麼不同,
在C#底下就用<傳入的型別>,
例如:List<string> myGen = new List<string>( );
例如:List<string> myGen = new List<string>( );
如何自定泛型類別
泛型類別宣告如同一般類別相似,只是宣告內容方法不一樣
泛型類別宣告:
class 類別名稱<T>[where 型別參數: 修件型別]{}
泛型方法宣告:
[存取限制修飾詞]返回型別 方法名稱(T|參數...)[where 型別參數: 絛件型別]{}
where T:struct限制為值型別where T:class限制為參考型別
where T:new()可以使用 new T()[沒有參數之建構子]
where T:[base class]限制為類別的子類別
where T:[interface]限制必須實作介面
where T:U(U是型別參數)限制為U的子類別
1.宣告泛型類別
class 類別名稱<T1,T2,....Tn)>
{
}
2.宣告泛型方法
public class myGeneric<T>
{
public void myTest(T myValue)
{
System.Type myType = myValue.GetType();
Console.WriteLine(myType);
}
}
3.引用泛型類別
myGeneric<int> myCom1 =new myGeneric<int>();
myCom1.myTest(1);
myGeneric<string> myCom2 = new myGeneric<string>();
myCom2.myTest("sdf");
myGeneric<double> myCom3 = new myGeneric<double>();
myCom3.myTest(12.2344);
不管引用任何型態,泛型類別都能全部接收。
運用泛型和集合,可以將資料類型作型別的分類,將特定型態的資料,透過集合來存取。
以前的傳統程式,要寫出這樣的功能,需要個別去寫出一個類別去使用,在.Net裡可以很輕易的就運用這樣的功能。
-雲遊山水為知已逍遙一生而忘齡- 電腦神手
運用泛型和集合,可以將資料類型作型別的分類,將特定型態的資料,透過集合來存取。
以前的傳統程式,要寫出這樣的功能,需要個別去寫出一個類別去使用,在.Net裡可以很輕易的就運用這樣的功能。
-雲遊山水為知已逍遙一生而忘齡- 電腦神手
不好意思可以請教您幾個問題嗎
回覆刪除因為剛接觸C#這部分,所以發生了許多看不太懂的窘境,在網路上我看到了一個簡短的資料樹的方法
namespace CSharpTree
{
public class TreeNode : IEnumerable>
{
public T Data { get; set; }
public TreeNode Parent { get; set; }
public ICollection> Children { get; set; }
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList>();
}
public TreeNode AddChild(T child)
{
TreeNode childNode = new TreeNode(child) { Parent = this };
this.Children.Add(childNode);
return childNode;
}
//other features ...
}
}
這是簡短的部分,在引用部分當我跟著他使用了字串時
TreeNode root = new TreeNode("root");
{
TreeNode node0 = root.AddChild("node0");
TreeNode node1 = root.AddChild("node1");
TreeNode node2 = root.AddChild("node2");
{
TreeNode node20 = node2.AddChild(null);
TreeNode node21 = node2.AddChild("node21");
{
TreeNode node210 = node21.AddChild("node210");
TreeNode node211 = node21.AddChild("node211");
}
}
TreeNode node3 = root.AddChild("node3");
{
TreeNode node30 = node3.AddChild("node30");
}
}
會出現無法使用建立出來的類別型式(root及它的內部方法AddChild)
請問這是不是我遺漏了什麼導致不能夠使用了
不好意思可以請教您幾個問題嗎
回覆刪除因為剛接觸C#這部分,所以發生了許多看不太懂的窘境,在網路上我看到了一個簡短的資料樹的方法
namespace CSharpTree
{
public class TreeNode : IEnumerable>
{
public T Data { get; set; }
public TreeNode Parent { get; set; }
public ICollection> Children { get; set; }
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList>();
}
public TreeNode AddChild(T child)
{
TreeNode childNode = new TreeNode(child) { Parent = this };
this.Children.Add(childNode);
return childNode;
}
//other features ...
}
}
這是簡短的部分,在引用部分當我跟著他使用了字串時
TreeNode root = new TreeNode("root");
{
TreeNode node0 = root.AddChild("node0");
TreeNode node1 = root.AddChild("node1");
TreeNode node2 = root.AddChild("node2");
{
TreeNode node20 = node2.AddChild(null);
TreeNode node21 = node2.AddChild("node21");
{
TreeNode node210 = node21.AddChild("node210");
TreeNode node211 = node21.AddChild("node211");
}
}
TreeNode node3 = root.AddChild("node3");
{
TreeNode node30 = node3.AddChild("node30");
}
}
會出現無法使用建立出來的類別型式(root及它的內部方法AddChild)
請問這是不是我遺漏了什麼導致不能夠使用了
不好意思可以請教您幾個問題嗎
回覆刪除因為剛接觸C#這部分,所以發生了許多看不太懂的窘境,在網路上我看到了一個簡短的資料樹的方法
namespace CSharpTree
{
public class TreeNode : IEnumerable>
{
public T Data { get; set; }
public TreeNode Parent { get; set; }
public ICollection> Children { get; set; }
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList>();
}
public TreeNode AddChild(T child)
{
TreeNode childNode = new TreeNode(child) { Parent = this };
this.Children.Add(childNode);
return childNode;
}
//other features ...
}
}
這是簡短的部分,在引用部分當我跟著他使用了字串時
TreeNode< string > root = new TreeNode("root");
{
TreeNode< string > node0 = root.AddChild("node0");
TreeNode< string > node1 = root.AddChild("node1");
TreeNode< string > node2 = root.AddChild("node2");
{
TreeNode< string > node20 = node2.AddChild(null);
TreeNode< string > node21 = node2.AddChild("node21");
{
TreeNode< string > node210 = node21.AddChild("node210");
TreeNode< string > node211 = node21.AddChild("node211");
}
}
TreeNode< string > node3 = root.AddChild("node3");
{
TreeNode< string > node30 = node3.AddChild("node30");
}
}
會出現無法使用建立出來的類別型式(root及它的內部方法AddChild)
請問這是不是我遺漏了什麼導致不能夠使用了
你的語法在一開始繼承上就寫法不對,IEnumerable裡要使用的物件要明確的定義:
回覆刪除TreeNode : IEnumerable>
root無法使用建立出的類別表示它無法對應你所對應的資料型別,在root.AddChild("node0")裡可以看出,此資料是屬於字串型別,
所以你在TreeNode的索引定義上要能指向可以定義的物件上:
變數的定義寫法要注意:
public T Data { get; set; }
public TreeNode Parent { get; set; }
public ICollection> Children { get; set; }
在處理自身定義時要能呈現有彈性的處理:
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList>();
this.ElementsIndex = new LinkedList>();
this.ElementsIndex.Add(this);
}
大致上的概念就是這樣。