当前位置:首页 > 网络编程 > 软件语言 > .NET > C#2.0 泛型约束

C#2.0 泛型约束

点击次数:60 次 发布日期:2008-11-06 07:52:13 作者:源代码网
源代码网推荐
广告载入中
3.泛型约束

3.1为什么要泛型约束

   看以下示例:

        public class LinkedList<K, T>

        {

              T Find(K key)

              public T this[K key]

              {

                   get {return Find(key);}

}

}

            LinkedList<int, string> list = new LinkedList<int, string>();

            list.AddHead(123,"AAA");

            list.AddHead(456,"BBB");

            string item=list[456];

            Debug.Assert(item=="BBB");

       Find方法实现:

        T Find(K key)

            {

                Node<K,T> current = m_Head;

                while(current.NextNode !=null)

                {

                    //因为编译器不知道 K(实例化时的实际类型)是否支持==运算符,例如,默认情况下,结构不提供这样的实现

                    if (current.Key==key)  //Will not compile

                        break ;

                    else

                        current =current .NextNode ;

                }

                return current.Item ;

            }

       Find方法的解决方法

         ---泛型增加一个派生约束(Derivation Constraints)



        //where 关键字

        //K:IComparable表示K只接受实现IComparable接口的类型

        public class LinkedList<K, T> where K:IComparable

        {

              T Find(K key)

            {

                Node<K,T> current = m_Head;

                while(current.NextNode !=null)

                {

                    if (current.Key.CompareTo(key)==0)

                        break ;

                    else

                        current =current.NextNode ;

                }

                return current.Item ;

                //Rest of the implementation

            }

        }

      3.2 在C#2.0中,所有的派生约束必须放在类的实际派生列表之后,如:


         public class LinkedList<K, T>:IEnumerable<T> where K:IComparable

         {……}

      3.3 通常,只需在需要的级别定一约束。比如:在Node节点定义IComparable<K>约束是没有意义的。如果一定要在Node上定义IComparable<K>约束,则LinkedList上也要定义约束。

         class Node<K,T>where K:ICloneable <K>

         {……}

        

         public class LinkedList<KeyType,DataType> where KeyType:IConvertible <KeyType>

         {

            Node<KeyType ,DataType> m_Head;

         }


      3.4 一个泛型参数撒谎能够约束多个接口(彼此用逗号分隔)

        public class LinkedList<K, T> where K : IComparable<K>, IConvertible

         { ......}

          3.5 在一个约束中最多只能使用一个基类,这是因为C#不支持实现的多重继承

            约束的基类不能是密封类或静态类,并且有编译器实施这一限制

            不能将System.Delegate或System.Arry约束为基类

            可以同时约束一个基类以及一个火多个接口,但是该基类必须首先出现在派生约束列表中

         public class LinkedList<K, T> where K :MyBaseClass ,IComparable<K>

         { ......}



3.5 在一个约束中最多只能使用一个基类,这是因为C#不支持实现的多重继承

            约束的基类不能是密封类或静态类,并且有编译器实施这一限制

            不能将System.Delegate或System.Arry约束为基类

            可以同时约束一个基类以及一个火多个接口,但是该基类必须首先出现在派生约束列表中

         public class LinkedList<K, T> where K :MyBaseClass ,IComparable<K>

         { ......}

      3.6 自定义的接口或基类必须与泛型参数具有一致的可见性

          即:

              正确的可见性

              public class MyBaseClass


              { }

              internal class MySubClass<T> where:MyBaseClass

              {}

              颠倒的可见性

              internal class MyBaseClass

              { }

              public class MySubClass<T> where:MyBaseClass

              {}

      3.7泛型约束—构造函数约束

           ·假设你要在一般类的内部实例化一个新的一般对象。问题在于,C#编译器不知道客户端将使用的类型参数是否具有匹配的构造函数,因而它将拒绝编译实例化行。

                    ·为了解决该问题,C#允许约束一般类型参数,以使其必须支持公共默认构造函数。这是使用new()约束完成的。

                            public Node<K,T>where T:new()

              {

                   public K Key;

                   public T item;

                   public Node<K,T>NextNode;

                   public Node()

                   {

                       Key =default(K);

                       item=new T();

                       NextNode=null;

                   }

              }

           ·可以将构造函数约束与派生约束组合起来,前提是构造函数约束出现在约束列表中的最后

                            public class LinkedList<K, T> where K : IComparable<K>, new()


              { ......}

      3.8 泛型约束----引用/值类型约束

                     · 可以使用struct约束将一般类型参数约束为值类型(例如,int 、bool和enum),或任何自定义结构

                            public class MyClass <T>where T:struct

              {…… }

                     · 同样,可以使用Class约束将一般类型参数约束为引用类型(类)

                            public class MyClass <T>where T:class


              {…… }

           ·不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类

                     ·不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类

                     ·虽然可以使用类和默认构造函数约束,但这样做并没有任何价值
                     ·可以将引用/值类型约束与接口与约束组合起来,前提是引用/值类型约束出现在约束列表的开头

源代码网推荐

源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华