文章目录
- 前言
- 模拟需求
- 场景模拟
- 重复性高的需求
- 初始类结构
- 继承优化
- 抽象类
- 需求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();
}
总结
不是说只能用泛型约束去解决问题,而且泛型约束和扩展方法更具有扩展性,低耦合的特点。大家可以根据自己代码的习惯选择性的使用。