熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#泛型編程基礎知識總結

2022-06-13   來源: .NET編程 

  在項目中通過對項目不斷更深的認識運用了設計模式就難免不運到開箱和裝箱操作通常的開箱和裝箱操作對系統的性能有一定的影響為了解決這一個問題其中一種解決方案是運用泛型來解決下面是C#泛型的簡單介紹和使用便於在項目中靈活運用

  一C#泛型演示

  class Stack<T>

  {

  private T[] store;

  private int size;

  public Stack()

  {store = new T[]; size = ;}

  public void Push(T x)

  {store[size++] = x; }

  public T Pop()

  {return store[size];}

  }

  二C# 泛型簡介

  Stack<int> x = new Stack<int>();

  xPush();

  所謂泛型即通過參數化類型來實現在同一份代碼上操作多種數據類型泛型編程是一種編程范式它利用參數化類型將類型抽象化從而實現更為靈活的復用C#泛型賦予了代碼更強的類型安全更好的復用更高的效率更清晰的約束

  三C#泛型機制簡介

  C#泛型能力由CLR在運行時支持區別於C++的編譯時模板機制和Java的編譯時茶匙發這使得泛型能力可以在各個支持CLR的語言之間進行無縫互操作C#泛型代碼在被編譯為IL代碼和元數據時采用特殊的占位符來表示泛型類型並用專有的IL指 令支持泛型操作而真正的泛型實例化工作以 ondemand 的方式發生在JIT編譯時

  四C#泛型編譯機制

  一輪編譯時編譯器只為Stack<T>類型產生泛型版的IL代碼與元數據——並不進行泛型類型的實例化T在中間只充當占位符JIT編譯時當JIT編譯器第一次遇到Stack<int>時將用int替換泛型版IL代碼與元數據中的T——進行泛型類型的實例化CLR為所有類型參數為引用類型的泛型類型產生同一份代碼但如果類型參數為值類型對每一個不同的值類型CLR將為其產生一份獨立的代碼

  五C#泛型的幾個特點

  如果實例化泛型類型的參數相同那麼JIT編譯器會重復使用該類型因此C#的動態泛型能力避免了C++靜態模板可能導致的代碼膨脹的問題

  C#泛型類型攜帶有豐富的元數據因此C#的泛型類型可以應用於強大的反射技術

  C#的泛型采用基類 接口 構造器 值類型/引用類型的約束方式來實現對類型參數的 顯式約束提高了類型安全的同時也喪失了C++模板基於簽名的隱式約束所具有的高靈活性

  六C#泛型類與結構

  class C<U V> {} //合法

  class D: C<stringint>{} //合法

  class E<U V>: C<U V> {} //合法

  class F<U V>: C<string int> {} //合法

  class G : C<U V> { } //非法

  C#除可單獨聲明泛型類型(包括類與結構)外也可在基類中包含泛型類型的聲明但基類如果是泛型類它的類型參數要麼已實例化要麼來源於子類(同樣是泛型類型)聲明的類型參數

  七泛型類型的成員

  class C<V>{

  public V f;   //聲明字段

  public D<V> f;   //作為其他泛型類型的參數

  public C(V x) {

  thisf = x;

  }

  }

  泛型類型的成員可以使用泛型類型聲明中的類型參數但類型參數如果沒有任何約束則只能在該類型上使用從SystemObject繼承的公有成員

  八泛型接口

  interface IList<T> {

  T[] GetElements();

  }

  interface IDictionary<KV> {

  void Add(K key V value);

  }

  // 泛型接口的類型參數要麼已實例化// 要麼來源於實現類聲明的類型參數

  class List<T> : IList<T> IDictionary<int T> {

  public T[] GetElements() { return null; }

  public void Add(int index T value) { }

  }

  九泛型委托

  delegate bool Predicate<T>(T value);

  class X {

  static bool F(int i) {}

  static bool G(string s) {}

  static void Main() {

  Predicate<string> p = G;

  Predicate<int> p = new Predicate<int>(F);

  }

  }

  十泛型方法

  支持在委托返回值和參數上應用參數類型這些參數類型同樣可以附帶合法的約束

  泛型方法簡介

  C#泛型機制只支持 在方法聲明上包含類型參數——即泛型方法

  C#泛型機制不支持在除方法外的其他成員(包括屬性事件索引器構造器析構器)的聲明上包含類型參數但這些成員本身可以包含在泛型類型中並使用泛型類型的類型參數泛型方法既可以包含在泛型類型中也可以包含在非泛型類型中

  十一泛型方法的聲明與調用

  public class Finder {

  // 泛型方法的聲明

  public static int Find<T>  ( T[] items  T item) {

  for(int i=;i<itemsLength;i++){

  if (items[i]Equals(item))  { return i; }

  }

  return ;

  }

  }

  // 泛型方法的調用

  int i=FinderFind<int> ( new int[]{} );

  十二泛型方法的重載

  class MyClass {

  void F<T>(T[] a int i); // 不可以構成重載方法

  void F<U>(U[] a int i);

  void F<T>(int x); //可以構成重載方法

  void F(int x);

  void F<T>(T t) where T : A; //不可以構成重載方法

  void F<T>(T t) where T : B;

  }

  十三泛型方法的重寫

  abstract class Base

  {

  public abstract T F<TU>(T t U u) where U: T;

  public abstract T G<T>(T t) where T: IComparable;

  }

  class Derived: Base{

  //合法的重寫約束被默認繼承

  public override X F<XY>(X x Y y)  {  }

  //非法的重寫指定任何約束都是多余的

  public override T G<T>(T t) where T: IComparable {}

  }

  十四泛型約束簡介

  C#泛型要求對所有泛型類型或泛型方法的類型參數的任何假定都要基於顯式的約束以維護C#所要求的類型安全顯式約束由where子句表達可以指定基類約束接口約束構造器約束值類型/引用類型約束共四種約束顯式約束並非必須如果沒有指定顯式約束泛型類型參數將只能訪問SystemObject類型中的公有方法

  十五基類約束

  class A  {    public void F() {?} }

  class B  {  public void F() {?} }

  class C<ST>

  where S: A   // S繼承自A

  where T: B   // T繼承自B

  {

  // 可以在類型為S的變量上調用F

  // 可以在類型為T的變量上調用F

  }

  十六接口約束

  interface IPrintable  {    void Print();  }

  interface IComparable<T> { int CompareTo(T v);}

  interface IKeyProvider<T> { T GetKey(); }

  class Dictionary<KV>

  where K: IComparable<K>

  where V: IPrintable IKeyProvider<K>

  {

  // 可以在類型為K的變量上調用CompareTo

  // 可以在類型為V的變量上調用Print和GetKey

  }

  十七構造器約束

  class A {

  class B {

  class C<T>

  {

  public A() { }  }

  public B(int i) { }  }

  }

  C<B> c=new C<B>();   //錯誤B沒有無參構造器

  where T : new()

  //可以在其中使用T t=new T();

  ?

  C<A> c=new C<A>();   //可以A有無參構造器

  十八值類型/引用類型約束

  public struct A {

  public class B{  ?

  class C<T>

  where T : struct

  {

  }

  }

  // T在這裡面是一個值類型

  C<A> c=new C<A>();   //可以A是一個值類型

  }

  C<B> c=new C<B>();   //錯誤B是一個引用類型


From:http://tw.wingwit.com/Article/program/net/201311/13090.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.