C#面试分享:单例模式
C#面试分享:单例模式
提问1:请给出单例模式的实现:
答:
public class Animal
{
private static Animal _instance = null;
private static readonly object _lock = new object();
public static Animal Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Animal();
}
}
}
return _instance;
}
}
public string Name { get; set; } = "Animal"
private Animal() {}
public void Print()
{
Console.WriteLine("i am " + Name);
}
}
提问2:继承会破坏单例模式吗?
分析:
说实话,当时这个问题把我给问懵了,没有想明白面试官想考察什么。
下面参考《Head First 设计模式》一书的相关问题,来做一些分析:
首先,就上文的代码而言,子类可以继承 Animal 吗?
答案显然是不能的,因为Animal的构造函数是私有(private)的。为了不破坏单例模式"唯一实例,全局访问点"这两个约束条件,我们把构造器改为 protected ,这样子类就能顺利继承Animal了。
第二点,我们假定所有的子类也是单例的,所以每个子类都应该实现 Instance 这么一个全局访问点,以下代码实现了继承自 Animal 的子类 Cat 单例模式:
public class Cat : Animal
{
private static Cat _instance = null;
private static readonly object _lock = new object();
public new static Cat Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Cat();
}
}
}
return _instance;
}
}
protected Cat()
{
Name = "cat";
}
}
测试:
Animal animal = Animal.Instance;
Animal cat = Cat.Instance;
animal.Print();
cat.Print();
打印结果:
i am animal
i am animal
这种结果显然是有问题的,原因就在于子类 Cat 的 Instance 是用 new 修饰的,cat对象调用的Instance属性其实还是父类 Animal 的Instance属性。
解决方法就是在父类中实现“注册器”,提供父类及其所有子类的“全局访问点”,以下就是修改后的父类 Animal 代码:
public class Animal
{
private static readonly IDictionary<Type, Animal> _dictionary = new ConcurrentDictionary<Type, Animal>();
static Animal()
{
_dictionary.Add(typeof(Animal), new Animal());
}
public static T GetInstance<T>() where T : Animal
{
var type = typeof(T);
if (!_dictionary.ContainsKey(type))
{
var constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
var constructor = constructors[0];
var animal = constructor.Invoke(null) as Animal;
_dictionary.Add(type, animal);
return animal as T;
}
return _dictionary[type] as T;
}
public string Name { get; protected set; }
protected Animal()
{
Name = "Animal";
}
public void Print()
{
Console.WriteLine("i am " + Name);
}
}
Cat代码
public class Cat : Animal
{
protected Cat()
{
Name = "Cat";
}
}
测试:
static void Main(string[] args)
{
Animal animal = Animal.GetInstance<Animal>();
Animal cat = Animal.GetInstance<Cat>();
animal.Print();
cat.Print();
Console.ReadLine();
}
输出:
i am Animal
i am Cat
C#面试分享:单例模式的更多相关文章
- 2017、2018面试分享(js面试题记录)记得点赞分享哦;让更多的人看到~~
2017面试分享(js面试题记录) 1. 最简单的一道题 '11' * 2 'a8' * 3 var a = 2, b = 3; var c = a+++b; // c = 5 2. 一道this的问 ...
- php程序猿面试分享
面试总结 今天去了北京著名IT公司进行PHP程序猿的面试.这是人生第一次么,怎么不紧张?我是不是有病.不是.这叫自信呵. 首先是做一些笔试题. 1.mysql数据库索引使用的数据结构?这样做的优点是? ...
- 2020.4面试分享(7面收5个offer)
都说金三银四是找工作的最佳时节,由于本人的个人职业规划跟目前工作内容不太相符(具体原因就不透露了,领导平时也要来这里逛,哈哈),四月份挑选了10多家公司投递简历(公司规模从几十人到上万人都有),参加了 ...
- 2020.4面试分享(7面收割5个offer)
都说金三银四是找工作的最佳时节,由于本人的个人职业规划跟目前工作内容不太相符(具体原因就不透露了,领导平时也要来这里逛,哈哈),四月份挑选了10多家公司投递简历(公司规模从几十人到上万人都有),参加了 ...
- 阿里巴巴前端面试分享-社招(p6)
借鉴了朋友的阿里面试经:(社招前端2年经验) 电话面 简单自我介绍, 做过哪些项目, 使用哪些技术栈 ? 如何看待前端框架选型 ? vue的如何实现双向绑定的 ? react 虚拟DOM 是什么? 如 ...
- cvte2018春招前端开发实习面试分享
编程题问题描述: 返回整数数组中出现次数第n多的数字(返回值可能有多个) 最近在找实习,面试二面最后出了一道这样的编程题,当时有思路但语法有错误,而且很紧张,最后没有运行出来,导致凉凉,回来重新思考了 ...
- 太原面经分享:如何在vue面试环节,展示你晋级阿里P6+的技术功底?
前言 一年一度紧张刺激的高考开始了,与此同时,我也没闲着,奔走在各大公司的前端面试环节,不断积累着经验,一路升级打怪. 最近两年,太原作为一个准二线城市,各大互联网公司的技术栈也在升级换代,假如你在太 ...
- java的设计模式 - 单例模式
java 面试中单例模式基本都是必考的,都有最推荐的方式,也不知道问来干嘛.下面记录一下 饿汉式(也不知道为何叫这个名字) public class Singleton { private stati ...
- 太原面经分享:如何用js实现返回斐波那契数列的第n个值的函数
面试攒经验,let's go! 值此高考来临之际,闲不住的我又双叒叕出发去面试攒经验了,去了公司交待一番流程后,面试官甩给了我一张A4纸,上面写着一道js算法笔试题(一开始我并不知道这是在考察js算法 ...
随机推荐
- ubuntu解压时中文出现乱码
一.乱码类似这样的:╫╩┴╧╖┤╤▌▓т╒╛╦┘╢╚│ 今天遇到需要上传十几G的图片,在wins上压缩成zip格式,在上传到服务器上,结果出现乱码.然后各种百度心塞. 最初查到原因: 这个主要是因为z ...
- C语言复习3_条件结构
if条件结构 if else 结构一般处理区间情况 #include <stdio.h> #include <stdlib.h> int main() { //打印剧情 dou ...
- C#单元测试,带你快速入门
注:本文示例环境 VS2017 XUnit 2.2.0 单元测试框架 xunit.runner.visualstudio 2.2.0 测试运行工具 Moq 4.7.10 模拟框架 为什么要编写单元测试 ...
- 使用Sublime Text 或 vs2017开发Node.js程序
在学习一门开发语言时,为了从简单的方式入手,有时候直接用Notepad开始敲代码.曾经我也这样干过,这样做简洁而不简单啊! 随着时间的流逝,人也变得懒惰起来,做事前总是想借助一些工具来搞事情.< ...
- #Java学习之路——基础阶段(第八篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- [Swift]LeetCode865. 具有所有最深结点的最小子树 | Smallest Subtree with all the Deepest Nodes
Given a binary tree rooted at root, the depth of each node is the shortest distance to the root. A n ...
- awk小例子_1_逆序排列
seq 3 | awk '{ lifo[NR]=$0 } END{ for(lno=NR;lno>-1;lno--){ print lifo[lno]; } }' 结果:3 2 1 空行(lno ...
- php设计模式2
代理模式 <?php /** * 代理模式:为其他对象提供一个代理以控制这个对象的访问 它是给某一个对象提供一个替代者,使之在client对象和subject对象之间编码更有效率. 代理可以提供 ...
- IdentityServer4之Implicit(隐式许可) —— oidc-client-js前后端分离
IdentityServer4之Implicit(隐式许可) —— oidc-client-js前后端分离 参考 官方文档:oidc-client-js:oidc-client是一个JavaScrip ...
- spring cloud + .net core实现微服务架构
1.新建spring boot项目 2.添加spring-cloud-starter-eureka-server依赖(需提供版本信息) <!-- https://mvnrepository.co ...