【C#】当重复使用一段代码倒计时时,定义接口类和通过实现类继承接口方式进行封装方法和体现代码灵活性

本文主要是介绍【C#】当重复使用一段代码倒计时时,定义接口类和通过实现类继承接口方式进行封装方法和体现代码灵活性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欢迎来到《小5讲堂》
大家好,我是全栈小5。
这是《C#》序列文章,每篇文章将以博主理解的角度展开讲解,
特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。
温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!

在这里插入图片描述

目录

  • 前言
  • 优化前
    • 界面
    • 代码
  • 优化后
    • 界面
    • 继承类
    • 代码
  • 常见情况
    • 报错提示
    • 解决方法
    • 属性作用
    • 封装
    • 继承
    • 多态

前言

上两篇文章已经通过静态方法和this扩展方式,实现了倒计时公共代码的封装。
通过代码的封装,不仅代码减少了,也提高了代码的可维护性,一举多得,何乐不为。
这也是编程最有魅力的地方,随着编码经验的增多以及不停的学习,就会满满理解和领悟一些知识点,理论以及设计思想。

【C#】当重复使用一段代码倒计时时,使用普通类和静态方法,实现简单的封装性、可扩展性、可维护性

【C#】当重复使用一段代码倒计时时,使用静态类和静态方法,实现简单的this扩展方法

优化前

优化前,是通过在每个窗体添加一段倒计时异步方法代码,然后窗体界面添加一个label标签用于显示当前实时时间。

界面

在这里插入图片描述
在这里插入图片描述

代码

/// <summary>
/// 倒计时
/// </summary>
private void CurrentTime()
{Task.Run(() =>{while (true){lbTime.Text = $"当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";Thread.Sleep(1000);}});
}

优化后

这次优化是通过静态类静态方法实现,并且是使用this进行扩展。
同时把控件初始化位置以及高宽度大小设置成独立的变量成员,可对其进行赋值,否则使用默认值。

界面

在这里插入图片描述

继承类

实现类对接口类进行继承,从下面可以知道,实现类必须实现接口定义好的成员和方式,否则就会提示下面报错信息
在这里插入图片描述

代码

  • 封装方法
/// <summary>
/// 接口类,通过继承实现方法
/// 1)接口不能包含实例字段,比如:public int x;
/// </summary>
public interface ITimeLabel
{int X { get; set; }int Y { get; set; }int Width { get; set; }int Height { get; set; }void Get(Form that);
}public class TimeLabelClass : ITimeLabel
{public int X { get; set; } = 50;public int Y { get; set; } = 50;public int Width { get; set; } = 179;public int Height { get; set; } = 15;public void Get(Form that){Label label = new Label();label.Location = new Point() { X = X, Y = Y };label.Width = Width;label.Height = Height;that.Controls.Add(label);Task.Run(() => {while (true){label.Text = $"当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";Thread.Sleep(1000);}});}
}
  • 窗体1
    这里直接实例化后就调用方法,这样就是使用了默认位置和大小值
private void Test1_Load(object sender, EventArgs e)
{//TimeLabel.Time(this, 50, 50);//this.TimeLabel();new TimeLabelClass().Get(this);
}private void button1_Click(object sender, EventArgs e)
{Test2 test2 = new Test2();test2.Show();
}
  • 窗体2
    这里对位置和大小值进行了重新赋值,体现了封装的灵活性
private void Test2_Load(object sender, EventArgs e)
{ITimeLabel timeLabel = new TimeLabelClass();timeLabel.X = 20;timeLabel.Y = 20;timeLabel.Width = 139;timeLabel.Height = 12;timeLabel.Get(this);
}

常见情况

报错提示

在窗体异步方法里操作主线程控件时,会提示错误,线程间操作无限:从不不是创建控件"lbTime"的线程访问它。
在这里插入图片描述

解决方法

可在构造函数里增加下面代码

/// <summary>
/// 构造函数
/// </summary>
public TestTemp()
{InitializeComponent();CheckForIllegalCrossThreadCalls = false;
}

属性作用

CheckForIllegalCrossThreadCalls 可以拆分成 4 个词:
1.Check:检查
2.For:为了
3.Illegal:非法的
4.CrossThreadCalls:跨线程调用
整体意思是:为了检查跨线程调用是否非法。

C# 中的 CheckForIllegalCrossThreadCalls 是一个属性,用于检查在多线程编程中是否存在潜在的跨线程调用问题。
它可以帮助开发人员在开发过程中更好地处理线程间的通信。

在 C# 中,UI 线程是用于处理用户界面操作的主线程,而其他操作(如网络请求、计算等)通常需要在后台线程中执行。
然而,直接在后台线程中访问 UI 控件是不安全的,可能会导致不可预测的结果和操作系统错误。
CheckForIllegalCrossThreadCalls 属性的作用是在调试模式下,检测程序是否存在不安全的跨线程调用。

当该属性设置为 true 时,在出现跨线程调用时,会引发一个异常,以提醒开发人员进行相应的处理。
当属性设置为 false 时,不会引发异常,但仍然可能导致不安全的操作。

这个属性主要用于帮助开发人员及时发现并修复由于线程之间的错误调用而导致的问题。
它可以提高应用程序的稳定性和可靠性,避免潜在的线程安全问题。
要注意的是,这个属性只在调试模式下起作用,在发布版本中不会进行检查。

#三大特性
C# 面向对象的三大特性是封装、继承和多态。

封装

它是指将对象的某些内部状态和行为封装起来,只暴露必要的接口供其他对象使用,并且隐藏其实现细节,从而保证了对象的安全性和可维护性。
比如:内部类成员、私有成员、保护类成员等

继承

它是指通过继承一个已有的类来创建一个新类,新类继承了父类的属性和方法,并可以新增或重写一些方法,从而在代码复用和扩展性方面提供了便利。
比如:交通工具,不同汽车都有公共的属性年份和品牌等,不同品牌和年份的车价格不同,继承共有属性的同时也增加了属于自己的价格方法

多态

它是指同一种类型的对象,在不同的情况下,可以有不同的状态和行为。在面向对象编程中,多态通常通过继承和接口实现。
比如:都是动物,猫狗动物发出的声音不同

温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。

这篇关于【C#】当重复使用一段代码倒计时时,定义接口类和通过实现类继承接口方式进行封装方法和体现代码灵活性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/609198

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义