模板約束

與C++模板不同,C#模板增加了對於泛化類的約束問題,泛化類約束共計4中類型:

基類約束:要求泛化類必須繼承至某個基類。

接口約束:要求泛化類必須實現某個接口。

構造函數約束:要求泛化類必須提供默認的構造函數。

值/引用數據類型約束:要求泛化類只能爲值類型或引用類型。

1. 基類約束,當出現多個約束時,基類約束必須放在最前面,基類約束中的基類不能是sealed class(密封類)和非值類型。

public class Base { 
    
    }

public class Derived: Base {
    
    }
public class TBase<T>
        where T : Base { 
    
    }

2.  接口約束,如下面的程序,如果未約束IComparable接口,方法就需要進行強制轉換爲IComparable接口,再調用CompareTo方法,轉換過程中可能會拋出異常或者出現C++大量無法定位源的錯誤信息。

public class TCompare<T> 
where T: System.IComparable<T>

    { 
       public void Method( T t1,  T t2)
        {
            Console.WriteLine("t1:{0},t2:{1},t1 < t2:{2}",t1,t2,t1.CompareTo(t2));
        }
    }
3. 構造函數約束:只支持默認構造器約束

public class TDerived<T>
        where T : new() { 
    
    }

4. 值/引用數據類型約束

public struct A { 
    
    };

    public struct TA<T>
        where T : struct { 
    
    }
其中Nullable<T>不能嵌套,即Nullable<Nullable<T>>,該項爲編譯器特殊規定,一個可空的”可空類型”是毫無意義的。
5. 約束繼承

當出現模板類約束繼承時,需將父類中的約束添加至子類中,而方法約束時,則無需將父類中的方法約束添加至子類中。

  public class TBase<T>
        where T : Base { 

        public virtual void Foo<T>(T t )
        where T:System.IComparable<T>
        {
    
        }
    }
  public class TDerived<T>
        where T : new() { 
    
    }

    public class TDerived2<T>:TBase<T>
       where T : Base,new()
    {
        public virtual void Foo<T>(T t)
        {

        }
    }

約束還有一些限制性的條件,如不能實現運算符約束、不支持OR選擇約束。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generic
{
    public struct A { 
    
    };

    public struct TA<T>
        where T : struct { 
    
    }

    public class Base { 
    
    }

    public class Derived: Base {
        Derived(int value) {}
    }

    public class TBase<T>
        where T : Base { 

        public virtual void Foo<T>(T t )
        where T:System.IComparable<T>
        {
    
        }
    }

    public class TDerived<T>
        where T : new() { 
    
    }

    public class TDerived2<T>:TBase<T>
       where T : Base,new()
    {
        public virtual void Foo<T>(T t)
        {

        }
    }


    public class TCompare<T> 
            where T: System.IComparable<T>

    { 
       public void Method( T t1,  T t2)
        {
            Console.WriteLine("t1:{0},t2:{1},t1 < t2:{2}",t1,t2,t1.CompareTo(t2));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            TCompare<int> t = new TCompare<int>();
            t.Method(1, 2);
            TBase<Derived> s = new TBase<Derived>();
            TA<TA<int>> ta = new TA<TA<int>>();
            TDerived<Base> td = new TDerived<Base>();
            Console.ReadLine();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章