泛型學習.
泛類學習
一.應用場景
1.效率.
2.易用,容錯.
3.處理同一類事情.
二.應用.
1.無論在聲明變量還是實例變量都要指定使用那個變量代替<T>
2.內部算法和數據操作保持不變
三.使用.
1.編譯器不知道使用將要指定的具體類型
2.派生約束.,以逗號分割多個約束.
為使用的一般類型參數分別指定約束.以空格分割.
基類約束(最多一個).
可以同時約束一個基類以及一個或多個接口,但是該基類必須首先出現在派生約束列表中
代碼
public class LinkedList where K : IComparable,IConvertible //多個約束以逗號分割
public class LinkedList where K : IComparable
where T : ICloneable
public class MyBaseClass
{...}
public class LinkedList where K : MyBaseClass
public class LinkedList where K : MyBaseClass, IComparable
3.構造函數約束
class Node where T : new()
{
public K Key;
public T Item;
public Node NextNode;
public Node()
{
Key = default(K);
Item = new T(); //構造函數使用.
NextNode = null;
}
}
public class LinkedList where K : IComparable
where T : ICloneable
public class MyBaseClass
{...}
public class LinkedList where K : MyBaseClass
public class LinkedList where K : MyBaseClass, IComparable
3.構造函數約束
class Node where T : new()
{
public K Key;
public T Item;
public Node NextNode;
public Node()
{
Key = default(K);
Item = new T(); //構造函數使用.
NextNode = null;
}
}
4.可以將構造函數約束與派生約束組合起來,前提是構造函數約束出現在約束列表中的最后:
public class LinkedList where K : IComparable,new()
5.引用/值類型約束
可以使用 struct 約束將一般類型參數約束為值類型(例如,int、bool 和 enum),或任何自定義結構:
public class MyClass where T : struct
{...}
//同樣,可以使用 class 約束將一般類型參數約束為引用類型(類):
public class MyClass where T : class
{...}
{...}
//同樣,可以使用 class 約束將一般類型參數約束為引用類型(類):
public class MyClass where T : class
{...}
6.編譯器允許您將一般類型參數顯式強制轉換到其他任何接口,但不能將其轉換到類:
代碼
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
//7.代碼塊 6. 對一般類型參數使用“is”和“as”運算符
public class MyClass
{
public void SomeMethod(T t)
{
if(t is int)
{...}
if(t is LinkedList)
{...}
string str = t as string;
if(str != null)
{...}
LinkedList list = t as LinkedList;
if(list != null)
{...}
}
}
8.一般類型參數的轉換.
泛型和強制類型轉換
C# 編譯器只允許將一般類型參數隱式強制轉換到 Object 或約束指定的類型,如代碼塊 5 所示。這樣的隱式強制類型轉換是類型安全的,因為可以在編譯時發現任何不兼容性。
代碼塊 5. 一般類型參數的隱式強制類型轉換
代碼
interface ISomeInterface
{...}
class BaseClass
{...}
class MyClass where T : BaseClass,ISomeInterface
{
void SomeMethod(T t)
{
ISomeInterface obj1 = t;
BaseClass obj2 = t;
object obj3 = t;
}
}
//編譯器允許您將一般類型參數顯式強制轉換到其他任何接口,但不能將其轉換到類:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
9.從泛型類繼承的類,要指明具體的參數.
public class BaseClass<T>
{...}
public class SubClass : BaseClass<int>
{...}
{...}
public class SubClass : BaseClass<int>
{...}
10.如果子類也是泛類,基類的約束需要在子類重新規范一邊
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
//2.1
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
public class BaseClass<T> where T : ISomeInterface
{...}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{...}
11 如果基類有泛型虛方法,子類可以重載,但是必須指明具體類型.
public class BaseClass<T>
{
public virtual T SomeMethod()
{...}
}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{...}
}
{
public virtual T SomeMethod()
{...}
}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{...}
}
12 但是如果子類也是泛型,則重載時也可使用子類的<T>:
public class SubClass<T>: BaseClass<T>
{
public override T SomeMethod()
{...}
}
{
public override T SomeMethod()
{...}
}
13. 泛類的其它泛型參數以及約束.
代碼
public void Clone<T2>(T2 target)
where T2 : EBaseResItem<T2>
{
foreach (var property in AllProperties)
{
var pName = property.PropertyInfo.Name;
var p2 = EBaseResItem<T2>.AllProperties.FirstOrDefault(p => p.PropertyInfo.Name == pName);
if (p2 != null)
{
this.LoadProperty(property.PropertyInfo, target.ReadProperty(p2.PropertyInfo));
}
}
}
where T2 : EBaseResItem<T2>
{
foreach (var property in AllProperties)
{
var pName = property.PropertyInfo.Name;
var p2 = EBaseResItem<T2>.AllProperties.FirstOrDefault(p => p.PropertyInfo.Name == pName);
if (p2 != null)
{
this.LoadProperty(property.PropertyInfo, target.ReadProperty(p2.PropertyInfo));
}
}
}
14 可以定義泛型接口.
public interface ISomeInterface<T>
{
T SomeMethod(T t);
}
{
T SomeMethod(T t);
}


浙公網安備 33010602011771號