C#泛型语法详解

 更新时间:2022年07月07日 14:32:13   作者:社会主义接班人  
本文详细讲解了C#中的泛型语法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

一、为什么要有泛型?

我们在写一些方法时可能会方法名相同,参数类型不同的方法,这种叫做重载。如果只是因为参数类型不同里面做的业务逻辑都是相同的,那可能就是复制粘贴方法,改变参数类型,例如一些排序算法,int、float、double等类型的排序,参数数组存的数据类型不一样,还有像根据索引找到List集合中的对象。可能这个对象是Person、Dog等对象,这样方法改变的只是参数类型,那就是能不能写一个方法,传递不同的参数类型呢?于是乎有了泛型。

二、什么是泛型?

泛型通过参数化类型来实现在同一份代码上操作多种数据类型。例如使用泛型的类型参数T,定义一个类Stack<T>,可以用Stack<int>、Stack<string>或Stack<Person>实例化它,从而使类Stack可以处理int、string、Person类型数据。这样可以避免运行时类型转换或封箱操作的代价和风险,类似C++的模板。泛型提醒的是将具体的东西模糊化,这与后面的反射正好相反。

三、泛型demo

1.泛型类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Generic
{
    public class Stack<T>
    {
        private T[] s;

        int pos;

        public Stack(int size)
        {
            s = new T[size];
            pos = 0;
        }

        public void Push(T val)
        {
            s[pos] = val;
            pos++;
        }

        public T Pop()
        {
            pos--;
            return s[pos];
        }

        public void display()
        {
            Console.WriteLine("Stack Push:");
            foreach (T i in s)
            {
                Console.WriteLine(i);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Generic
{
    class Program
    {
        static void Main(string[] args)
        {
            Stack<int> s1 = new Stack<int>(2);
            s1.Push(1);
            s1.Push(2);
            s1.display();

            Console.WriteLine("Stack Pop:");
            Console.WriteLine(s1.Pop());
            Console.WriteLine(s1.Pop());

            Stack<string> s2 = new Stack<string>(2);
            s2.Push(@"One");
            s2.Push(@"Two");
            s2.display();

            Console.WriteLine("Stack Pop:");
            Console.WriteLine(s2.Pop());
            Console.WriteLine(s2.Pop());

            Console.ReadLine();
        }
    }
}

上面定义了一个泛型类,主要是维护一个栈,栈里存放T类型的数据,在demo中可以定义int、string类型的栈,这样就很方便,使用一套代码可以维护多种数据类型。如果没有这个可能还要维护double、float等代码。

2.泛型方法

上面是泛型类,主要是在类层面进行参数化,我们还可以在更小的层面,在函数上进行泛型化。

我们可以在上面Mina类中定义一个静态的泛型方法,用来获取找数值在数组中的位置。

public static int Find<T>(T[] valus, T val)
{
    for (int i = 0; i < valus.Length; i++)
    {
        if (valus[i].Equals(val))
        {
            return i;
        }
    }
    return -1;
}

我们可以用上面的方法来查找int数组、float数组

int val = 4;
int pos = Find<int>(new int[] {1,2,3,4,5 },val);
Console.WriteLine(string.Format("int Pos:{0}",pos));

float val1 = 4;
pos = Find<float>(new float[] { 1, 2, 3, 4, 5 }, val1);
Console.WriteLine(string.Format("float Pos:{0}", pos));
Console.ReadLine();

下面是两个demo的输出

四、约束

约束是指对泛型类型参数施加限制,用于限制可以传递到该类型参数的类型种类。如果使用某个约束不允许的类型来实例化,则会产生编译时错误。约束使用where关键字指定。

约束有4种类型:

  • 1.基类约束

指定编译器泛型类型参数必须派生自特定基类

修饰符 class 类名<类型参数列表> where 类型参数:基类名

{ 类体}

  • 2.接口约束

指定编译器泛型类型参数必须派生自特定接口

修饰符 class 类名<类型参数列表> where 类型参数:接口名

{ 类体}

  • 3.默认构造函数约束

指示编译器泛型类型参数公开了默认的公共构造函数(不带任何参数的公共构造函数)

修饰符 class 类名<类型参数列表> where 类型参数:new ()

{ 类体}

  • 4.引用/值类型约束

指示编译器泛型类型参数必须是引用类型或值类型

修饰符 class 类名<类型参数列表> where 类型参数:struct(或class)

{ 类体}

可以对同一类型参数使用多个约束,并且约束自身可以也可以是泛型类型,多个约束之间用逗号隔开。

五、泛型委托

泛型委托主要是想讲一下Action<T>和Func<TResult>两个委托,因为这两个在Linq中是经常见到的。

  • Action<T>只能委托必须是无返回值的方法
  • Fun<TResult>只是委托必须有返回值的方法

不管是不是泛型委托,只要是委托委托那能用Lamdba表达式,因为不管Lamdba表达式还是匿名函数其实都是将函数变量化。

下面简单的来做的demo说下两个的用法,这个会了基本linq会了一半了。

Action<string> action = s => {
	Console.WriteLine(s);
};
action("cuiyanwei");
           

Func<int, int, int> func = (int a, int b)=>{
	return a + b;
};
int result=func(1, 2);
Console.WriteLine("sum:{0}",result);

Console.ReadLine();

上面其实都是将函数做为变量,这也是委托的思想。action是实例化了一个只有一个字符串参数没有返回值得函数变量。func是实例化了一个有两个int类型的参数返回值为int的函数变量。下面来看下输出结果:

我们可以看到通过Lamdba表达式和泛型的结合,算是又方便了开发者们,更加方便实用。

到此这篇关于C#泛型语法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

  • 深入浅析C#中的var和dynamic

    深入浅析C#中的var和dynamic

    这篇文章给大家介绍了C#中的var和dynamic的相关知识,var和dynamic的本质区别是类型判断的时间不同,前者是编译时,后者是运行时。具体内容详情大家通过本文学习下吧
    2018-05-05
  • 详解C#扩展方法原理及其使用

    详解C#扩展方法原理及其使用

    这篇文章主要介绍了C#扩展方法原理及其使用的的相关资料,文中代码非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C#使用HttpWebRequest与HttpWebResponse模拟用户登录

    C#使用HttpWebRequest与HttpWebResponse模拟用户登录

    这篇文章主要为大家详细介绍了C#使用HttpWebRequest与HttpWebResponse模拟用户登录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • unity实现多点触控代码

    unity实现多点触控代码

    这篇文章主要介绍了unity实现多点触控代码,我最近在学习Unity游戏引擎。先从Unity平面开始,本章介绍Unity 平面上的多点触摸。有需要的小伙伴参考下。
    2015-03-03
  • WPF中TreeView控件的用法

    WPF中TreeView控件的用法

    这篇文章介绍了WPF中TreeView控件的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中互操作性简介

    C#中互操作性简介

    这篇文章主要介绍了C#中互操作性的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • 解析c#在未出现异常情况下查看当前调用堆栈的解决方法

    解析c#在未出现异常情况下查看当前调用堆栈的解决方法

    本篇文章是对c#在未出现异常情况下查看当前调用堆栈的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C#泛型的使用及示例详解

    C#泛型的使用及示例详解

    这篇文章主要介绍了C#泛型的使用及示例,本文通过例子个大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • 用C#把文件转换为XML的代码

    用C#把文件转换为XML的代码

    用C#把文件转换为XML的代码...
    2007-03-03
  • C#多线程学习之(六)互斥对象用法实例

    C#多线程学习之(六)互斥对象用法实例

    这篇文章主要介绍了C#多线程学习之互斥对象用法,实例分析了C#中互斥对象的使用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04

最新评论

?


http://www.vxiaotou.com