zoukankan      html  css  js  c++  java
  • 泛型学习.

                                       泛类学习

    一.应用场景
       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;
       }
    }

    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 

    {...}

    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>
      {...}

    10.如果子类也是泛类,基类的约束需要在子类重新规范一边

      public class 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
      {...}

    11  如果基类有泛型虚方法,子类可以重载,但是必须指明具体类型.

    public class BaseClass<T>

       
    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()
       {...}
    }

    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));
                    }
                }
            }

    14 可以定义泛型接口.

      public interface ISomeInterface<T>
     {
        T SomeMethod(T t);
     }
  • 相关阅读:
    ceph 高可用部署
    ceph安装
    openstack 命令
    ceph
    go test 怎么做测试
    govendor
    wrap 缓存。。。
    python中if __name__ == '__main__': 的解析
    pythton 字典的使用,字典的方法
    python 基础 如何让程序接收参数,最简单用sys.argv[]来获取
  • 原文地址:https://www.cnblogs.com/SouthAurora/p/1713701.html
Copyright © 2011-2022 走看看