C#泛型设计需要注意的一个小陷阱

 更新时间:2019年03月07日 09:25:02   作者:詹姆斯.辛  
这篇文章主要给大家介绍了关于C#泛型设计需要注意的一个小陷阱,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

距离上次发表博客已经有几年了. 对于没能坚持更新博客,实在是感觉到甚是惭愧.

闲言少叙, 直接切入主题.

什么是泛型

我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型不同。有没有一种办法,在方法中传入通用的数据类型,这样不就可以合并代码了吗?泛型的出现就是专门解决这个问题的。

但泛型就简单吗?当然不是,继续往下看..

背景

最近一直在对于公司一个网络通信服务程序使用.net core 进行重构.重构的目的有两个:一是让程序能够跨平台运行. 二是优化程序代码结构是程序的可维护性有所提升.  重构的过程主要由我来设计底层的架构. 在这个过程中,由于我对C# 泛型的理解还不够深入,所以在这个方面我就犯了个错误. 希望本文能把我犯的这个错误阐述清楚, 如果能帮助园里其他朋友避免这个问题当然是最好的了.

早前的设计

先用一张图来描述早前的代码结构

Singleton<T> :是一个单例的基类, 用来实现单例模式.

Base<T> : 则是一个基础类,它有一些静态的属性和方法(例如访问Redis,kafka,数据库等). 这些属性和方法提供给 Child1 和 Child2 去使用.

Child1 和Child2: 相当于不同模块的业务逻辑实现.

 我期望的结果是Base<T>里面的静态成员在整个程序运行期间只有一份.

代码的实现

Singleton

public abstract class Singleton<T> where T : new()
 {
  /// <summary>
  /// 锁定对象
  /// </summary>
  private static readonly object locker = new object();
  /// <summary>
  /// T 的实例
  /// </summary>
  static T instance = default(T);
  /// <summary>
  /// T 的实例
  /// </summary>
  public static T Instance
  {
   get
   {
    if (null == instance)
    {
     lock (locker)
     {
      if (null == instance)
      {
       instance = new T();
      }
     }
    }
    return instance;
   }
  }
 }

Base

public class Base<T> : Singleton<T> where T : new()
{
 protected static object Object { set; get; }

 static Base()
 {
  Object = new object();
 }
}

Child1 和Child2

public class Child1 : Base<Child1>
{
}

public class Child2 : Base<Child2>
{
}

我以为 Base的静态构造函数只会执行一次. 可是当我在程序里使用 Child1.Instance Child2.Instance 时发现, Base的静态构造函数被执行了2次. 那么Child1.Instance的Object和Child2.Instance的Object对象一定不是同一个.

那么问题出现在什么地方了呢? 答案其实挺简单的:系统认为 Base<Child1> Base<Child2>并不相同. 相当于在系统里定义了Base_Child1 和Base_Child2两个类. 如果我们这么理解这个问题 ,那么Base的静态构造函数被执行了2次就不难理解了.(我觉得我已经把这个问题的成因描述清楚了,如果您没理解,欢迎在下面评论.)

如果要达到我设计的目标应该怎么做呢?

修正的设计

还是先上类图.

Base:

public class Base
{
 protected static object Object { set; get; }

 static Base()
 {
  Object = new object();
 }
}

Singleton:

public abstract class Singleton<T>: Base where T : new()
{
  /// <summary>
  /// 锁定对象
  /// </summary>
  private static readonly object locker = new object();
  /// <summary>
  /// T 的实例
  /// </summary>
  static T instance = default(T);
  /// <summary>
  /// T 的实例
  /// </summary>
  public static T Instance
  {
   get
   {
    if (null == instance)
    {
     lock (locker)
     {
      if (null == instance)
      {
       instance = new T();
      }
     }
    }
    return instance;
   }
  }
}

Child1 和Child2:

public class Child1 : Singleton<Child1>
{
}

public class Child2 : Singleton<Child2>
{
}

由Singleton 来继承Base.然后Child1 和Child2来继承Singleton. 这样问题就都解决了.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • C#设置自定义文件图标实现双击启动(修改注册表)

    C#设置自定义文件图标实现双击启动(修改注册表)

    这篇文章介绍的是利用C#设置自定义文件图标,然后实现双击启动的功能,文章给出了示例代码,介绍的很详细,有需要的可以参考借鉴。
    2016-08-08
  • C# .NET中Socket简单实用框架的使用教程

    C# .NET中Socket简单实用框架的使用教程

    最近一个项目因为要用到Socket传输问题,所以决定学习一下,将自己学习的内容总结分享出来,下面这篇文章主要给大家介绍了关于C# .NET中Socket简单实用框架使用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-09-09
  • C#中的委托介绍

    C#中的委托介绍

    这篇文章主要介绍了C#中的委托介绍,本文讲解了声明委托的方式、匿名方法、多播委托等内容,需要的朋友可以参考下
    2015-01-01
  • C#实现的pdf生成图片文字水印类实例

    C#实现的pdf生成图片文字水印类实例

    这篇文章主要介绍了C#实现的pdf生成图片文字水印类,结合完整实例形式分析了C#针对pdf文件的创建、添加文字、水印等相关操作技巧,需要的朋友可以参考下
    2017-09-09
  • C#基于UDP实现的P2P语音聊天工具

    C#基于UDP实现的P2P语音聊天工具

    这篇文章主要是一个应用,使用udp传送语音和文本等信息。在这个系统中没有服务端和客户端,相互通讯都是直接相互联系的,能够很好的实现效果
    2015-09-09
  • 解析使用C# lock同时访问共享数据

    解析使用C# lock同时访问共享数据

    本篇文章是对使用C# lock同时访问共享数据进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • C#将HashTable中键列表或值列表复制到一维数组的方法

    C#将HashTable中键列表或值列表复制到一维数组的方法

    这篇文章主要介绍了C#将HashTable中键列表或值列表复制到一维数组中方法,涉及C#操作HashTable的相关技巧,需要的朋友可以参考下
    2015-04-04
  • C# yield在WCF中的错误使用(二)

    C# yield在WCF中的错误使用(二)

    这篇文章主要介绍了C# yield在WCF中的错误使用(二),本文讲解的内容据说是99%的开发人员都有可能犯的错误,需要的朋友可以参考下
    2015-04-04
  • c#转换全角半角方法示例

    c#转换全角半角方法示例

    这篇文章主要介绍了c#如何转换全角半角,大家可以看一下下面的代码方法,可以参考一下
    2013-12-12
  • WPF实现曲线数据展示

    WPF实现曲线数据展示

    这篇文章将以动数据分析为例为大家详细介绍wpf实现曲线数据展示与函数曲线展示的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下
    2024-12-12

最新评论