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; }

}
/// 
/// 使用基类优化代码
/// 
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; }

}

区别就是抽象类无法实例化
C# 继承,抽象,接口,泛型约束,扩展方法_第1张图片

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

需求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();
    }
 
}

/// 
/// 使用基类优化代码
/// 
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);
        }
        /// 
        /// 泛型约束DeviceBase基类
        /// 
        /// 
        /// 
        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
{
    /// 
    /// 扩展方法是更高级的泛型方法,但是需要一个静态类扩展
    /// 
    /// 
    /// 
    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);
}

/// 
/// 泛型约束也可以约束接口
/// 
/// 
/// 
public static void GetData<T>(T model) where T : IDevice
{
    model.Connect();
    model.Send();
    model.Recive();
    model.Close();
}

总结

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

你可能感兴趣的:(C#,C#,小轮子,c#,.net)