(八)CSharp-泛型中的方法结构委托接口(2)

news2024/11/18 21:40:26

一、泛型方法

泛型方法可以在泛型和非泛型类以及结构和接口中声明。

请添加图片描述

1、声明泛型方法

泛型方法具有类型参数列表和可选的约束。

  • 泛型方法有两个参数列表。

    • 封闭在圆括号内的方法参数列表。
    • 封闭在尖括号内的类型参数列表。
  • 要声明泛型方法,需要:

    • 在方法名称之后和方法参数列表之前放置类型参数列表;
    • 在方法参数列表后放置可选的约束子句。
public void PrintData(S,T)(S p,T t) where S: Person
{
...
}

//<S,T>:类型参数列表
//(Sp,T t):方法参数列表
//where S: Person:约束子句

2、调用泛型方法

void DoStuff<T1,T2>(T1 t1,T2 t2)
{
T1 someVar = t1;
T2 otherVar = t2;
}

DoStuff<short,int>(sVal,iVal);
DoStuff<int,short>(iVal,lVal);
//<short,int>:类型实参

3、推断类型

编译可以从方法参数中推断类型参数,我们可以省略类型参数和调用中的尖括号。

DoStuff(sVal,iVal);

泛型方法的示例

//非泛型类
    class Simple
    {
        //泛型方法
        static public void ReverseAndPrint<T>(T[] arr)
        {
            Array.Reverse(arr);

            //使用类型实参 T
            foreach (T item in arr)
                Console.Write($"{item.ToString() },");

            Console.WriteLine("");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //创建各种类型的数组
            var intArray = new int[] { 3, 5, 7, 9, 11 };
            var stringArray = new string[] { "first", "second", "third" };
            var doubleArray = new double[] { 3.567, 7.891, 2.345 };

            Simple.ReverseAndPrint<int>(intArray);//调用方法
            Simple.ReverseAndPrint(intArray);//推断类型并调用

            Simple.ReverseAndPrint<string>(stringArray);
            Simple.ReverseAndPrint(stringArray);

            Simple.ReverseAndPrint<double>(doubleArray);
            Simple.ReverseAndPrint(doubleArray);
            Console.ReadKey();
        }
    }

二、扩展方法和泛型类

和非泛型类一样,泛型类的扩展方法:

  • 必须声明为 static;
  • 必须是静态类的成员;
  • 第一个参数类型中必须有关键字 this,后面是扩展的泛型类的名字。
   static class ExtendHolder
    {
        public static void Print<T>(this Holder<T> h)
        {
            T[] vals = h.GetValues();
            Console.WriteLine($"{ vals[0] },\t{ vals[1] },\t{ vals[2] }");
        }
    }

    class Holder<T>
    {
        T[] Vals = new T[3];

        public Holder(T v0,T v1,T v2)
        {
            Vals[0] = v0;Vals[1] = v1;Vals[2] = v2;
        }

        public T[] GetValues() { return Vals; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var intHolder = new Holder<int>(3, 5, 7);
            var stringHolder = new Holder<string>("a1", "b2", "c3");
            intHolder.Print();
            stringHolder.Print();
            Console.ReadKey();
        }
    }

三、泛型结构

与泛型类相似,泛型结构可以有类型参数和约束。(规则和条件跟泛型类一样)

    //泛型结构
    struct PieceOfData<T>
    {
        public PieceOfData(T value){ _data = value; }
        private T _data;
        public T Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        //PieceOfData<int>(10):构造类型
            var intData = new PieceOfData<int>(10);
            var stringData = new PieceOfData<string>("Hi there.");

            Console.WriteLine($"intData  =={ intData.Data }");
            Console.WriteLine($"stringData  =={ stringData.Data }");

            Console.ReadKey();
        }
    }

输出结果:

intData == 10
stringData == Hi there.

四、泛型委托

1、泛型委托

泛型委托和非泛型委托相似,不过类型参数决定了能接受什么样的方法。

delegate R MyDelegate<T,R>(T value);
//R:返回类型
//<T,R>:类型参数
//(T value):委托形参

有两个参数列表: 委托形参列表和类型参数列表。

类型参数的范围包括:

  • 返回类型;
  • 形参列表;
  • 约束子句。
 //泛型委托
    delegate void MyDelegate<T>(T value);

    class Simple
    {
        //方法匹配委托
        static public void PrintString(string s)
        {
            Console.WriteLine(s);
        }

        static public void PrintUpperString(string s)
        {
            Console.WriteLine($"{s.ToUpper()}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //创建委托的实例
            var mDel = new MyDelegate<string>(Simple.PrintString);
            mDel += Simple.PrintUpperString;//添加方法

            mDel("Hi There.");//调用委托
            Console.ReadKey();
        }
    }

输出结果:

Hi There.
HI THERE.

2、另一个泛型委托示例

C# 的 LINQ 特性大量使用了泛型委托。

    //泛型委托
    public delegate TR Func<T1, T2, TR>(T1 P1, T2 P2);

    class Simple
    {
        //方法匹配委托
        static public string PrintString(int p1, int p2)
        {
            int total = p1 + p2;
            return total.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //创建委托实例
            var myDel = new Func<int, int, string>(Simple.PrintString);
            Console.WriteLine($"Total:{ myDel(15,13) }");//调用委托
            Console.ReadKey();
        }
    }

输出结果:

Total:28

五、泛型接口

1、泛型接口

泛型接口的声明和非泛型接口的声明差不多,但是需要在接口名称之后的尖括号中放置类型参数。

泛型类型中实现泛型接口。

  //泛型接口
    interface IMyIfc<T>
    {
        T ReturnIt(T inValue);
    }

    //实现泛型接口
    class Simple<S>: IMyIfc<S>
    {
        public S ReturnIt(S inValue)
        {
            return inValue;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var trivInt = new Simple<int>();
            var trivString = new Simple<string>();

            Console.WriteLine($"{ trivInt.ReturnIt(5) }");
            Console.WriteLine($"{ trivString.ReturnIt("Hi there.") }");

            Console.ReadKey();
        }
    }

输出结果:

5
Hi there.

2、使用泛型接口的示例

非泛型类型中实现泛型接口。

    //泛型接口
    interface IMyIfc<T>
    {
        T ReturnIt(T inValue);
    }

    //非泛型类
    //
    class Simple: IMyIfc<int>, IMyIfc<string>
    {
        //实现 int 类型接口
        public int ReturnIt(int inValue)
        {
            return inValue;
        }

        //实现 string 类型接口
        public string ReturnIt(string inValue)
        {
            return inValue;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Simple trivial = new Simple();
            Console.WriteLine($"{ trivial.ReturnIt(5) }");
            Console.WriteLine($"{ trivial.ReturnIt("Hi there.") }");

            Console.ReadKey();
        }
    }

输出结果:

5
Hi there.

3、泛型接口的实现必须唯一

实现泛型类型接口时,必须保证类型实参的组合不会在类型中产生两个重复的接口。

    //泛型接口
    interface IMyIfc<T>
    {
        T ReturnIt(T inValue);
    }
    
//错误:IMyIfc<int>, IMyIfc<S>,
//如果 S 为 int 类型就跟第一个接口重复了
    class Simple<S>: IMyIfc<int>, IMyIfc<S>
    {
        //实现 int 类型接口
        public int ReturnIt(int inValue)
        {
            return inValue;
        }

        //实现 string 类型接口
        public S ReturnIt(S inValue)
        {
            return inValue;
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/633828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java程序猿搬砖笔记(十四)

文章目录 MySQL自定义排序用locate本质是数字排序case when then...语法排序field()函数排序 阿里云Maven镜像仓库无法下载spring-cloud-dependencies依赖问题MySQL更新同一个表的同个字段解决方法一(推荐)解决方法二 SpringBoot返回的JSON中的null转换为空字符串Spring的相关注…

OpenGL光照之光照贴图

文章目录 漫反射贴图镜面光贴图放射光贴图代码 每个物体都拥有自己独特的材质从而对光照做出不同的反应的方法。这样子能够很容易在一个光照的场景中给每个物体一个独特的外观&#xff0c;但是这仍不能对一个物体的视觉输出提供足够多的灵活性。 我们将整个物体的材质定义为一个…

Linux命令:lsof

目录 一、理论 1.lsof 二、实验 1.无参数 2.-p 参数 3.-l 参数 4. -u 参数 5.-c 参数 6.-d 参数 7.fileName 8. -i 参数 一、理论 1.lsof (1)概念 命令 lsof &#xff08; list opened files &#xff09;负责列出系统中已经打开的文件&#xff0c;包括普通文件&a…

【uni-app】使用uni-app实现简单的登录注册功能

文章目录 前言一、页面布局二、注册页面1.注册接口使用2.注册成功提示3.注册成功页面跳转4.完整代码 三、登录页面1.登录接口使用2.本地存储使用3.完整代码 总结 前言 大家好&#xff0c;今天和大家分享一下如何在uni-app中实现简单的登录注册功能。 首先你需要掌握一下知识点…

【SQL Server】数据库开发指南(九)详细讲解 MS-SQL 触发器的的创建、修改、应用与适用场景

本系列博文还在更新中&#xff0c;收录在专栏&#xff1a;#MS-SQL Server 专栏中。 本系列文章列表如下&#xff1a; 【SQL Server】 Linux 运维下对 SQL Server 进行安装、升级、回滚、卸载操作 【SQL Server】数据库开发指南&#xff08;一&#xff09;数据库设计的核心概念…

UE特效案例 —— 火堆

一&#xff0c;环境配置 创建默认地形Landscape&#xff0c;如给地形上材质需确定比例&#xff1b;添加环境主光源DirectionalLight&#xff0c;设置相应的强度和颜色&#xff1b;PostProcessVolume设置曝光&#xff0c;设置Min/Max Brightness为1&#xff1b; 与关闭Game Sett…

03并发进程

文章目录 哲学家进餐问题1.利用结构型信号量解决哲学家进餐问题解决方案1&#xff1a;每次最多允许四位哲学家就餐 2.利用AND型信号量解决哲学家进餐问题 生产者-消费者问题1.利用结构型信号量解决生产者-----消费者问题单缓冲区生产者-消费者问题多缓冲区 2.利用AND型信号量解…

高并发编程:并发容器

一、概述 常见的容器如下图&#xff0c;我们会挑选高并发中常用的容器进行介绍。 二、ConcurrentHashMap 个ConcurrentHashMap提高效率主要提高在读上面&#xff0c;由于它往里插的时候内部又做了各种各样的判断&#xff0c;本来是链表的&#xff0c;到8之后又变成了红黑树&a…

详细讲解!selenium:解决页面元素display:none的方法

目录 前言&#xff1a; 1、具体问题 2、解决方案 代码解析&#xff1a; 结尾&#xff1a; 前言&#xff1a; 在进行 Web 自动化测试时&#xff0c;页面元素的可见性对测试结果的准确性和稳定性至关重要。然而&#xff0c;有些时候页面元素会被设置为 display:none&#x…

亚马逊云科技出海日,助推出海业务全球拓展突飞猛进

出海路漫漫&#xff0c;企业开拓全球市场而孤军奋战&#xff0c;常常会感到力不从心。好的产品有了&#xff0c;渠道有了&#xff0c;供应链有了&#xff0c;还要自己从0-1搭建存储、网络和架构&#xff1f;营销季来了想趁机冲一波销量&#xff0c;还要自己运维本地IDC、大促来…

10.无监督学习之K-means算法

10.1 无监督学习的定义 监督学习&#xff1a;我们有一些列标签&#xff0c;然后用假设函数去拟合它 无监督学习&#xff1a;给出的数据不带任何标签。对于无监督学习来说&#xff0c;需要做的就是将数据输入到算法中&#xff0c;让算法找到一些隐含在数据中的结构&#xff0c;通…

C语言—程序环境和预处理

程序环境和预处理 程序的翻译环境和执行环境编译、链接翻译环境编译预处理&#xff08;预编译&#xff09;编译汇编 链接 编译环境几个阶段的总结 运行环境&#xff08;执行环境&#xff09;预处理详解预定义符号#define#define 定义标识符#define 定义宏#define 替换规则#和##…

【MySQL】数据库中表的操作详解

【MySQL】数据库表的基本操作 一、表的创建二、查看表结构三、修改表结构3.1 添加表中字段3.2 修改表中字段3.3 删除表中字段3.4 修改表名3.5 修改列名 四、删除表 温馨提示&#xff1a;这里的表操作指的是表结构的操作&#xff0c;属于DDL数据定义语言 一、表的创建 CREATE …

hooks组件+例子+底层机制

1.React组件分类 函数组件 1.不具备"状态、ref、周期函数"等内容&#xff0c;第一次渲染完毕后&#xff0c;无法基于组件内部的操作来控制其更新&#xff0c;因此称之为静态组件!。但是具备属性及插槽&#xff0c;父组件可以控制其重新渲染 2.渲染流程简单&#xff…

Same Symbol | 哇咔咔!!!盘点一下表达矩阵中重复基因的处理方法!~

1写在前面 医院天天叫我们填问卷&#xff0c;我真是不能理解。&#x1fae0; 动不动就问我们对医院的福利满意吗&#xff0c;对自己的收入满意吗&#xff0c;觉不觉得工作负荷太重了&#xff1f;&#xff1f;&#xff1f;&#x1f642; 我们满不满意&#xff0c;觉不觉得累&…

大学物理(上)-期末知识点结合习题复习(2)——运动的描述考点总结、质点运动学-牛顿运动定律

目录 运动的描述 期末考点 质点运动学 牛顿运动定律知识点 题1(牛顿第二定律) 题目描述 题解 题2 (圆周运动) 题目描述 题解 运动的描述 期末考点 1.速度和加速度的推导 平均速度平均速度反映的只是在一段时间内位移的变化&#xff0c;如果需要精准的地知道质点在…

chatgpt赋能python:Python如何判断奇偶数?

Python如何判断奇偶数&#xff1f; 作为一门功能强大且容易上手的编程语言&#xff0c;Python具有许多有用的工具和功能。其中之一就是判断奇偶数。在本文中&#xff0c;我们将介绍Python中判断奇偶数的不同方法。 H1&#xff1a;Python中的基本判断方法 Python中最基本的判…

(八)CSharp-泛型协变和逆变(3)

一、协变和逆变 可变性分为三种&#xff1a; 协变、逆变和不变。 协变和逆变&#xff1a; 为泛型接口和泛型委托添加了一个处理类型转换问题的扩展。 问题&#xff1a; 当两个类对象是继承与派生的关系时&#xff0c;由于编译器通过泛型实例化时没法确认它们之间的关系&…

(数组) 1991. 找到数组的中间位置 ——【Leetcode每日一题】

❓1991. 找到数组的中间位置 难度&#xff1a;简单 给你一个下标从 0 开始的整数数组 nums &#xff0c;请你找到 最左边 的中间位置 middleIndex &#xff08;也就是所有可能中间位置下标最小的一个&#xff09;。 中间位置 middleIndex 是满足 nums[0] nums[1] ... num…

FTP协议详解

文章目录 1 FTP概述2 实验环境3 FTP详解3.1 文件传输过程3.2 报文格式3.3 数据连接3.4 主动模式3.5 被动模式3.6 匿名服务器 4 总结 1 FTP概述 FTP为File Transfer Protocol的缩写&#xff0c;即文件传输协议&#xff0c;是TCP/IP 协议族中的协议之一。FTP是一个用于在计算机网…