当前位置: 首页 > news >正文

C# 继承,抽象,接口,泛型约束,扩展方法

文章目录

  • 前言
  • 模拟需求
    • 场景模拟
      • 重复性高的需求
        • 初始类结构
        • 继承优化
          • 抽象类
        • 需求1:打印CreateTime
          • 方法1:使用重载
          • 方法2:基类函数
          • 方法3:泛型约束
          • 方法3.1:普通泛型方法
          • 方法3.2:高级泛型约束,扩展方法
        • 总结
      • 番外篇:泛型方法和接口
        • 泛型约束抽象接口
  • 总结

前言

以前计算机本科学习的时候,我就知道了继承,重载,接口,抽象,泛型等概念。本章优先讲解继承,接口,抽象,泛型这一组概念。如果说继承,抽象只是为了标准化代码,规范程序编写的话,那么泛型约束就是给于了继承抽象这个写法的必要性。

c# 继承

浅谈C#中的抽象类(abstract)和接口(interface)

C#泛型约束

模拟需求

因为我干的是上位机工作,这里我就讲解一下我用到的场景。上位机的代码重复性很高,泛型约束就是用于解决此类问题。

场景模拟

我是A公司,我有多种(为了简单按两种算)产品,这2种产品有一下两个特质

  • 每个产品存数据库的字段有完全相同的3个字段
    • Id:数据库Id
    • DeivceId:设备唯一Id,全部种类产品唯一的Id。
    • CreateTime:数据录入数据库时间

重复性高的需求

我们现在有个需求,给每个类添加一个打印CreateTime的方法

初始类结构
 public class DeviceA{public string DeviceId { get; set; }public long Id { get; set; }    public DateTime CreateTime { get; set; }public string ValueA {  get; set; }}public class DeviceB{public string DeviceId { get; set; }public long Id { get; set; }public DateTime CreateTime { get; set; }public string ValueB { get; set; }}
继承优化

继承的目的就是为了减少重复的字段

public class DeviceA:DeviceBase
{public string ValueA {  get; set; }
}public class DeviceB : DeviceBase
{public string ValueB { get; set; }}
/// <summary>
/// 使用基类优化代码
/// </summary>
public class DeviceBase
{public string DeviceId { get; set; }public long Id { get; set; }public DateTime CreateTime { get; set; }
}
抽象类

我们也可以在基类上面添加abstract关键字

public abstract class DeviceBase
{public string DeviceId { get; set; }public long Id { get; set; }public DateTime CreateTime { get; set; }}

区别就是抽象类无法实例化
在这里插入图片描述

那么抽象类的意义就是为了告诉你,我的基类是没有任何实际意义的,我单纯就是为了继承用的

需求1:打印CreateTime
方法1:使用重载
static void Main(string[] args)
{var DeviceA = new DeviceA() { CreateTime = DateTime.Now};var DeviceB = new DeviceB() { CreateTime = DateTime.Now };PrintCreateTime(DeviceA);PrintCreateTime(DeviceB);
}
public static void PrintCreateTime(DeviceA deviceA)
{Console.WriteLine($"{deviceA.CreateTime}");
}public static void PrintCreateTime(DeviceB deviceB)
{Console.WriteLine($"{deviceB.CreateTime}");
}
方法2:基类函数
internal class Program
{static void Main(string[] args){var DeviceA = new DeviceA() { CreateTime = DateTime.Now};var DeviceB = new DeviceB() { CreateTime = DateTime.Now };DeviceA.PrintCreateTime();DeviceB.PrintCreateTime();}}/// <summary>
/// 使用基类优化代码
/// </summary>
public class DeviceBase
{·······public void PrintCreateTime(){Console.WriteLine(CreateTime.ToString());}
}
方法3:泛型约束
方法3.1:普通泛型方法
        static void Main(string[] args){var DeviceA = new DeviceA() { CreateTime = DateTime.Now};var DeviceB = new DeviceB() { CreateTime = DateTime.Now };PrintCreateTime(DeviceA);PrintCreateTime(DeviceB);}/// <summary>/// 泛型约束DeviceBase基类/// </summary>/// <typeparam name="T"></typeparam>/// <param name="model"></param>public static void PrintCreateTime<T>(T model)where T : DeviceBase{Console.WriteLine(model.CreateTime.ToString());}
方法3.2:高级泛型约束,扩展方法

C#小轮子:扩展方法

internal class Program
{static void Main(string[] args){var DeviceA = new DeviceA() { CreateTime = DateTime.Now};var DeviceB = new DeviceB() { CreateTime = DateTime.Now };DeviceA.PrintCreateTime();DeviceB.PrintCreateTime();}}public static class DeviceExtension
{/// <summary>/// 扩展方法是更高级的泛型方法,但是需要一个静态类扩展/// </summary>/// <typeparam name="T"></typeparam>/// <param name="model"></param>public static void PrintCreateTime<T>(this T model) where T : DeviceBase{Console.WriteLine(model.CreateTime.ToString());}
}
总结
优点缺点
重载更灵活,每个类都可以定制重复性高
基类方法降低重复度耦合度高,过多会导致基类臃肿,不符合属性类规范
泛型约束降低重复度,耦合度低,易于扩展。不能访问基类以外的属性
扩展方法最强的扩展性,完美代替基类方法需要单独一个静态类

属性类:是我自己的规范。就是基础的属性类只有属性和构造函数,没有方法。

番外篇:泛型方法和接口

有些时候我们设备类的逻辑特别的复杂,比如每个产品都有四个方法:

  • 连接
  • 发送
  • 接受
  • 关闭连接
public interface IDevice
{public void Connect();public void Send();public void Recive();public void Close();}
public class DeviceA : DeviceBase, IDevice
{public string ValueA {  get; set; }public void Close(){throw new NotImplementedException();}public void Connect(){throw new NotImplementedException();}public void Recive(){throw new NotImplementedException();}public void Send(){throw new NotImplementedException();}
}public class DeviceB : DeviceBase, IDevice
{public string ValueB { get; set; }public void Close(){throw new NotImplementedException();}public void Connect(){throw new NotImplementedException();}public void Recive(){throw new NotImplementedException();}public void Send(){throw new NotImplementedException();}
}
泛型约束抽象接口
static void Main(string[] args)
{var DeviceA = new DeviceA() { CreateTime = DateTime.Now};var DeviceB = new DeviceB() { CreateTime = DateTime.Now };GetData(DeviceA);GetData(DeviceB);
}/// <summary>
/// 泛型约束也可以约束接口
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
public static void GetData<T>(T model) where T : IDevice
{model.Connect();model.Send();model.Recive();model.Close();
}

总结

不是说只能用泛型约束去解决问题,而且泛型约束和扩展方法更具有扩展性,低耦合的特点。大家可以根据自己代码的习惯选择性的使用。

相关文章:

C# 继承,抽象,接口,泛型约束,扩展方法

文章目录 前言模拟需求场景模拟重复性高的需求初始类结构继承优化抽象类 需求1&#xff1a;打印CreateTime方法1&#xff1a;使用重载方法2&#xff1a;基类函数方法3&#xff1a;泛型约束方法3.1&#xff1a;普通泛型方法方法3.2&#xff1a;高级泛型约束&#xff0c;扩展方法…...

mysql的备份和恢复

备份&#xff1a;完全备份 增量备份 完全备份&#xff1a;将整个数据库完整的进行备份 增量备份&#xff1a;在完全备份的基础之上&#xff0c;对后续新增的内容进行备份 备份的需求 1、在生产环境中&#xff0c;数据的安全至关重要&#xff0c;任何数据的都可能产生非常严重…...

【机器学习3】有监督学习经典分类算法

1 支持向量机 在现实世界的机器学习领域&#xff0c; SVM涵盖了各个方面的知识&#xff0c; 也是面试题目中常见的基础模型。 SVM的分类结果仅依赖于支持向量&#xff0c;对于任意线性可分的两组点&#xff0c;它 们在SVM分类的超平面上的投影都是线性不可分的。 2逻辑回归 …...

lv11 嵌入式开发 计算机硬件基础 1

目录 1 导学 1.1回顾及导学 1.2 嵌入式系统分层 1.3 linux底层开发 2 ARM体系结构与接口技术课程导学 3 计算机基础 3.1 计算机的进制 3.2 计算机组成 3.3 总线 4 多级存储结构与地址空间 4.1 多级存储概念 4.2 地址空间 5 CPU工作原理 6 练习 1 导学 1.1回顾及导…...

【Linux】vim

文章目录 一、vim是什么&#xff1f;二 、命令模式三、插入模式四、底行模式五、vim配置 一、vim是什么&#xff1f; Vim是一个强大的文本编辑器&#xff0c;它是Vi的增强版&#xff0c;支持多种语法高亮、插件扩展、多模式操作等功能。Vim有三种基本的工作模式&#xff1a;命…...

cstring函数

string 1.char str[]类型 fgets(s,10000,stdin) cin.getline(cin,10000) strlen(str) sizeof 求静态数组长度 2.string类型 getline(cin,a) cin.getline(cin,10000) str.lenth() str.size() cin 遇到空格就停止 3.gets 函数 char str[20]; gets(str); 4.puts 函…...

【owt】p2p client mfc 工程梳理

1年前构建的,已经搞不清楚了。所以梳理下,争取能用较新的webrtc版本做测试。最早肯定用这个测试跑通过 【owt】p2p Signaling Server 运行、与OWT-P2P-MFC 交互过程及信令分析官方的mfc客户端 估计是构造了多个不同的webrc版本的客户端...

pandas教程:Hierarchical Indexing 分层索引、排序和统计

文章目录 Chapter 8 Data Wrangling: Join, Combine, and Reshape&#xff08;数据加工&#xff1a;加入, 结合, 变型&#xff09;8.1 Hierarchical Indexing&#xff08;分层索引&#xff09;1 Reordering and Sorting Levels&#xff08;重排序和层级排序&#xff09;2 Summa…...

Redis 扩展 RedisBloom 插件,解决缓存击穿、穿透

文章目录 一、概述二、编译准备2.1 升级 make2.2 安装 Python3 三、编译 RedisBloom四、测试 RedisBloom五、应用场景5.1 缓存击穿5.2 缓存穿透5.3 原理总结 六、存在的问题 如果您对Redis的了解不够深入请关注本栏目&#xff0c;本栏目包括Redis安装&#xff0c;Redis配置文件…...

VBA技术资料MF80:选择文件及文件夹

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…...

网络层:控制平面

路由选择算法 路由选择算法就是为了在端到端的数据传输中&#xff0c;选择路径上路由器的最好的路径。通常&#xff0c;一条好的路径指具有最低开销的路径。最低开销路径是指源和目的地之间具有最低开销的一条路。 根据集中式还是分散式来划分 集中式路由选择算法&#xff1a…...

Ubuntu 系统内核 kernel panic

Ubuntu 系统内核 kernel panic 不能进入系统&#xff1a;报错end kernel panic -not syncing: attemped to kill init! exit code 0x00000100 系统启动的时候&#xff0c;按下‘e’键进入grub编辑界面&#xff0c;编辑grub菜单&#xff0c;选择“kernel /vmlinuz-XXXXro root…...

【flink】RowData copy/clone方式

说明&#xff1a;一般用户常用的是GenericRowData。flink内部则多使用BinaryRowData。 方法一、循环解决(不推荐)&#xff1a; 代码较为复杂需要根据RowType获取到内部fields的logicalType&#xff0c;再使用RowData.createFieldGetter方法创建fieldGetters。 public static …...

网页图标工具

工具地址...

掌动智能:功能测试及拨测主要功能

在企业中对于功能测试及拨测而言&#xff0c;用户只需提供应用包和产品文档&#xff0c;由资深测试专家设计并执行测试&#xff0c;覆盖核心场景&#xff0c;包含特定业务流程以及行业通用特殊场景&#xff0c;支持需求定制。 执行过程严格监控&#xff0c;依据应用功能和业务需…...

第11章 Java集合(二)

目录 内容说明 章节内容 一、Set接口 二、HashSet集合 三、LinkedHashSet集合 四、TreeSet集合...

Transformer和ELMo模型、word2vec、独热编码(one-hot编码)之间的关系

下面简要概述了Transformer和ELMo模型、word2vec、独热编码&#xff08;one-hot编码&#xff09;之间的关系&#xff1a; 独热编码&#xff08;One-hot Encoding&#xff09;是一种最基本的词表示方法&#xff0c;将词表示为高维稀疏向量。它与ELMo、word2vec和Transformer的关…...

您与1秒钟测量两千个尺寸之间仅差一台智能测径仪!

随着产线的发展&#xff0c;自动化程度越来越高&#xff0c;生产速度越来越快&#xff0c;人们对产品的品质要求越来越高&#xff0c;对检测也提出了更高的要求。传统的检测与测量手段已经很难满足测量效率要求&#xff0c;业内迫切需要一种新型高效率的测量设备。 产线多种多样…...

k8s之service五种负载均衡byte的区别

1&#xff0c;什么是Service&#xff1f; 1.1 Service的概念​ 在k8s中&#xff0c;service 是一个固定接入层&#xff0c;客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端pod&#xff0c;这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件&a…...

Unity项目转微信小游戏保姆教程,繁杂问题解决,及微信小游戏平台简单性能测试

前言 借着某人需求&#xff0c;做了一波简单的技术调研&#xff1a;将Unity项目转换为微信小游戏。 本文主要内容&#xff1a;Unity转换小游戏的步骤&#xff0c;遇到问题的解决方法&#xff0c;以及简单的性能测试对比 微信小游戏的限制 微信小游戏对程序包体大小有严格限制…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...