C#语法之泛型的多种应用

本篇文章主要介绍泛型的应用。

泛型是.NET  work 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性、类型安全性和效率。

泛型的定义

下面定义了一个普通类和一个泛型类,我们可以明确看到泛型类和普通类最大的区别就是多了一个<T>。

所以,这个<T>就标记了,这个类是泛型类。其中这个T,也可以写成A,B,C,D或其他字符。

public class Generic
{
  public String Name;
}
public class Generic<T>
{
  public T Name;
}

泛型,顾名思义,就是泛指的类型。好比男人,女人,白人,黑人,可以泛称为【人】。

但类型只能是一个类型。 那么泛型和类型之间是什么关系呢?

其实很简单,泛型在定义的时候,是泛指类型;在使用的时候,就需要被指定,到底使用哪个类型。

即,使用时,就不在是泛指类型,而是特定类型。

好比,定义时,定义了一个人。但在使用时,必须明确指定,到底是黑人还是白人。

泛型的使用

泛型类跟普通类的使用方式一样,都需要实例化对象,再由对象来调用内部的属性或方法。

下面代码实例化了泛型Generic,实例化时,还指定了该泛型Generic的指定类型为String。

所以要给泛型Generic的属性Name赋值,就需要赋值字符串类型的值。

public static void Excute()
{
  Generic<String> gs = new Generic<String>();
  gs.Name = "Kiba518";
}

下面代码定义了一个Int类型的泛型Generic。

public static void Excute()
{
  Generic<int> gs = new Generic<int>();
  gs.Name = 518;
}

泛型的默认值

泛型的默认值,如下面代码所示。需要使用default(T)来赋值。

不管泛型到底是String,int,bool或者是一个Class类型,都可以被自动赋值。

public static void Excute()
{
  Generic<int> gs = new Generic<int>();
  gs.Name = 518;
  Generic<Task> gsTask = new Generic<Task>();
  gsTask.Name = new Task(()=> {
    Console.WriteLine("Kiba518");
  });
}

public class Generic<T>
{
  public T Name = default(T);
}

泛型的约束

在泛型类中,有个特别的约束可供我们使用。

当我们不显示的声明时,这个约束不存在。但当我们显示的声明的时候,这个约束就会执行。

下面,我们来看看这个特别的约束。

public static void Excute()
{
  Generic<FanXing> gFanXing = new Generic<FanXing>();
  Generic< > gFanXing = new Generic< >();
  //Generic<string> gs = new Generic<string>(); 这样定义会报错
}
public class Generic<T> where T :
{
  public T Name = default(T);
}
public class
{
  public string Name { get; set; }
}
public class FanXing :
{
  public new string Name { get; set; }
}

如上面代码所示,【where T :  】就是这个特别的约束。

当显示声明这个约束的时候,定义会限制泛型的类型。

什么是限制泛型的类型呢?

很简单,泛型T,是泛指某一个类型。我们在定义泛型类时,还需显示的指定类型,此时我们显示指定的类型,要受这个限制。

这个限制就是指【where T :  】。

它的限制是,要求我们指定的类型T必须是 ,或者该类型继承自 ,如FanXing类。

泛型的函数

在C#中,泛型不仅可以用于类,还可以直接用于函数。

具体使用方式如下:

public static void Excute()
{
  GenericFunc gf = new GenericFunc();
  gf.FanXingFunc<FanXing>(new FanXing() { Name="Kiba518"});
}
public class GenericFunc
{
  public void FanXingFunc<T>(T obj)
  {
    Console.WriteLine(obj.GetType());
  }
}

很简单,调用泛型函数的时候,指定泛型函数的[指定类型]即可。

但是,这里我们发现一个问题,那就是,在泛型函数里,使用泛型对象的时候,我们发现对象都是 类型的。

那我们如果想使用泛型对象里的属性和方法时,要怎么办呢?

也很简单,反射就可以了。

下面我们添加一个反射函数GetPropertyValue,专门用来获取属性。

public class GenericFunc
{
  public void FanXingFunc<T>(T obj)
  {
    var name = GetPropertyValue(obj, "Name");
    Console.WriteLine(name);
  }
  public  GetPropertyValue( obj, string name)
  {
     drv1 = obj.GetType().GetProperty(name).GetValue(obj, null);
    return drv1;
  }
}

输出结果如下:

这样我们就得到了我们想要的结果,如果想使用泛型类里的函数,道理也一样,只需要用反射来调用即可。

结语

看到这里,有些同学可能会觉得泛型很复杂,连使用其对象下的属性,都得反射,太繁琐了,还不如不用呢。

有这样想法的同学,心里想想就好了,如果对老司机这么说,他肯定会内心默默的微笑,然后对你说,你想的没错。

然后,你就没有然后了。

泛型的应用,开篇已经说了,主要用在提高代码的可重用性、类型安全性和效率上。

如果只是定义一个类,调用一个属性,那泛型的存在就是鸡肋。

但事实上,我们的系统永远只有更复杂,更复杂,更复杂。因此泛型才有了用武之地。

----------------------------------------------------------------------------------------------------

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈c# 泛型类的应用

    泛型类泛型类封装不是特定于具体数据类型的操作. 泛型类最常用于集合,如链接列表.哈希表.堆栈.队列.树等. 像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关.对大多集合类的操作,推荐使用 .NET Framework 类库中所提供的类.(1)泛型类可以继承具体类.封闭式构造.开放式构造基类. 复制代码 代码如下: class BaseNode { }class BaseNodeGeneric<T> { }// 继承具体类class NodeConcrete<

  • C#语法之泛型的多种应用

    本篇文章主要介绍泛型的应用. 泛型是.NET  work 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了一个普通类和一个泛型类,我们可以明确看到泛型类和普通类最大的区别就是多了一个<T>. 所以,这个<T>就标记了,这个类是泛型类.其中这个T,也可以写成A,B,C,D或其他字符. public class Generic { public String Name; } public class Generic<T>

  • Java 7菱形语法与泛型构造器实例分析

    本文实例讲述了Java 7菱形语法与泛型构造器.分享给大家供大家参考,具体如下: 一 实战--泛型构造器 1 代码 class Foo { public <T> Foo(T t) { System.out.println(t); } } public class GenericConstructor { public static void main(String[] args) { // 泛型构造器中的T参数为String. new Foo("疯狂Java讲义"); //

  • Java语法关于泛型与类型擦除的分析

    泛型与类型擦除 泛型,JDK 1.5新特性,本质是参数化类型(Parametersized Type) 的应用,即所操作的数据类型被指定为一个参数.这种参数类型可用在: 类 接口 方法 的创建中, 分别称为: 泛型类 泛型接口 泛型方法 在Java还没有泛型的版本时.只能通过: Object 是所有类型的父类 类型强制转换 两个特性协作实现类型泛化.例如,在哈希表的存取中,JDK 1.5之前使用HashMap的get() 方法,返回值就是个Object.由于Java语言里面所有的类型都维承于ja

  • 带大家认识Java语法之泛型与通配符

    目录 ️前面的话️ 1.泛型 1.1泛型的用法 1.1.1泛型的概念 1.1.2泛型类 1.1.3类型推导 1.2裸类型 1.3擦除机制 1.3.1关于泛型数组 1.3.2泛型的编译与擦除 1.4泛型的上界 1.4.1泛型的上界 1.4.2特殊的泛型上界 1.4.3泛型方法 1.4.4类型推导 2.通配符 2.1通配符的概念 2.2通配符的上界 2.3通配符的下界 总结 ️前面的话️ 本篇文章带大家认识Java语法——泛型与通配符,泛型和通配符是一个非常抽象的概念,简单来说,两者都可以将类型作为

  • Java详细分析讲解泛型

    目录 1.泛型概念 2.泛型的使用 2.1泛型类语法 2.2泛型方法语法 2.3泛型接口语法 2.4泛型在main方法中的使用 3.擦除机制 4.泛型的上界 5.通配符 5.1通配符的上界 5.2通配符的下界 6.包装类 6.1装箱和拆箱 1.泛型概念 泛型就是将类型参数化 所谓类型参数化就是将类型定义成参数的形式,然后在使用此类型的时候的时候再传入具体的类型 到这我们可以看出来:泛型在定义的时候是不知道具体类型的,需要在使用的时候传入具体的类型,泛型可以用在类.接口和方法中,这样做的好处是一个

  • Java 中的语法糖,真甜

    我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 我们在日常开发中经常会使用到诸如泛型.自动拆箱和装箱.内部类.增强 for 循环.try-with-resources 语法.lambda 表达式等,我们只觉得用的很爽,因为这些特性能够帮助我们减轻开发工作量:但我们未曾认真研究过这些特性的本质是什么,那么这篇文章,cxuan 就来为你揭开这些特性背后的真相. 语法糖 在聊之前我们需要先了解一下 语法

  • Java泛型T,E,K,V,N,?与Object区别和含义

    目录 什么是泛型 泛型方法 语法规则 泛型标记符 泛型类 类型通配符 ? ?extendsT ?superT T和? T和Object 总结 通常我们在看一些源码时,发现全是T.?,晕乎乎的:sob:.于是,把泛型掌握好十分重要! 什么是泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 泛型有什么好处?写个例子一目了然: 我

  • Java lambda表达式与泛型整理总结

    目录 泛型 泛型的语法定义 泛型的使用语法 泛型总结 从泛型类派生子类 泛型接口 lambda表达式 lambda表达式概念 lambda表达式格式 泛型 泛型的语法定义 class 类名 <泛型标识,泛型标识,…>{ private 泛型标识1,变量名:常用的泛型标识:T,E,K,V } 里面正常写法 public class GenericDemo<K> { //定义数组 private K[] arr; } 泛型的使用语法 类名<具体的数据> 对象名 = new

  • 在 TypeScript 中使用泛型的方法

    目录 1. 泛型语法 2. 在函数中使用泛型 (1)分配泛型参数 (2)直接传递类型参数 (3)默认类型参数 (4)类型参数约束 3. 在接口.类和类型中使用泛型 (1)接口和类中的泛型 (2)自定义类型中的泛型 4. 使用泛型创建映射类型 5. 使用泛型创建条件类型 (1)基础条件类型 (2)高级条件类型 6. 小结 前言: 泛型是静态类型语言的基本特征,允许将类型作为参数传递给另一个类型.函数.或者其他结构.TypeScript 支持泛型作为将类型安全引入组件的一种方式.这些组件接受参数和返

  • TypeScript类型系统自定义数据类型教程示例

    目录 TypeScript 类型系统和自定义数据类型 什么是类型系统 函数类型 类型别名 可选参数 默认参数 函数重载 接口类型 可选属性 只读属性 接口扩展 多重接口声明 接口的索引签名 用接口描述函数 类类型 implements关键字 类的静态端类型和实例端类型 将 this 作为类型 将 this 作为参数 枚举 枚举类型 枚举的成员类型 枚举的成员 字面量类型 联合类型 交叉类型 泛型 泛型函数 泛型接口 泛型类 在工厂函数中使用泛型 泛型约束 在泛型约束中使用类型参数 在泛型中使用条

随机推荐