泛型学习.

                                   泛类学习

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

 

 

 

posted @   SouthAurora  Views(230)  Comments(0Edit  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示