泛型学习.

                                   泛类学习

一.应用场景
   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);
 }
原文地址:https://www.cnblogs.com/SouthAurora/p/1713701.html