知识提纲

C#属性

C#单例模式

0.自用超级简单式

namespace ConsoleApp2
{//工具类class Utils{private static Utils instance = null;public static Utils Instance{get{if(instance == null){instance = new Utils();}return instance;}}}
}

1.单线程单例模式

        public sealed class Singleton{public static Singleton instance = null;private Singleton() { }public static Singleton Instance{get{if (instance == null)instance = new Singleton();return instance;}}}

实现很简单,理解起来也不难,但是有个致命的缺点:线程不安全,两个线程可能同事检测到 instance==null成立,因为有可能在一瞬间创建两个。其实在多线程运行时,即使已经在内存中创建了实例,但是内存模型并不能保证新的instance能够看见其它线程所创建的实例。因此这种方法不推荐。下面看看线程安全的方法:

2.简单线程安全

 public sealed class Singleton2{private static Singleton2 instance = null;private static readonly object padlock = new object();private Singleton2() { }public static Singleton2 Instance{get{lock(padlock){if (instance == null)instance = new Singleton2();return instance;}}}}

变化不大,基于前面的分析,这个只是添加了一个object成员以此来实现锁。这种方法是线程安全的,每个线程要创建实例时,都要先去得锁,然后再判断是否为空,也就是保证多线程运行时,只有一个线程能进行进行实例化,而一旦一个线程实例化后,后面的线程取到锁后,就会发现实例已经创建。但是这个方法也有一个明显的缺点:假设线程足够多,100个吧,每一个线程在进行if(instance==null)判断时,都到等到某一个线程退出后将锁获得。所以会导致性能问题。改进的办法就是多进行以此判断,如果instance==null是FALSE,那自然没必要在等待锁,再去判断一次。

3.双层验证下的多线程安全

 public sealed class Singleton2{private static Singleton2 instance = null;private static readonly object padlock = new object();private Singleton2() { }public static Singleton2 Instance{get{if(null==instance){lock (padlock){if (instance == null)instance = new Singleton2();}}return instance;}}}

4.更高效的单例模式——饿汉模式

        public sealed class Singleton3{private static readonly Singleton3 instance = new Singleton3();static Singleton3() { }private Singleton3() { }public static Singleton3 Instance{get{return instance;}}}

正如你看到的,这个似乎比前面两种实现都要简单,它是如何保证线程安全的呢?对于每个AppDomain,在C#中类的实例被构造或者静态成员被引用时,静态构造函数才会执行,而且只执行一次。由于这个类在一加载就被实例化,因此,效率上要比前面实现高的多。

那为何叫饿汉模式呢?这是因为相对于第2、3的实现方式,Singleton必选被引用一次后才会将自己实例化,这种成为懒汉式;而当下,无论我们在程序中用不用,编译器都会实例化一个对象,所以就成为“饿汉模式”

那我们看另外一种懒汉模式:

5. 懒汉模式——利用嵌套类

public sealed class Singleton
{private Singleton(){}public static Singleton Instance { get { return Nested.instance; } }private class Nested{// Explicit static constructor to tell C# compiler// not to mark type as beforefieldinitstatic Nested(){}internal static readonly Singleton instance = new Singleton();}
}

6. 使用net4之后的Lazy泛型

在.net4之后,可以使用System.Lazy<T>类型实现迟实例化,你唯一需要做的就是传递一个代理便令给单例类的构造函数,可以用lambda表达式轻松实现:

public sealed class Singleton
{private static readonly Lazy<Singleton> lazy =new Lazy<Singleton>(() => new Singleton());public static Singleton Instance { get { return lazy.Value; } }private Singleton(){}
}

上面的代码会隐式的调用LazyThreadSafetyMode.ExecutionAndPublication以实现lazy<Singleton>线程安全模式.

public override string Tostring

这个是一个很简单的类,他包含两个property name和Age,这里我们就overrid了ToString的函数,你可以使用任何你想要的方式来重写这个函数,只要return一个string就可以了。

        class Person{public string Name { get; set; }public int Age { get; set; }public override string ToString(){return String.Format("Name is {0}, Age is {1}", Name, Age);}}

调用的代码如下:

Person person = new Person { Name = "Jason", Age = 20 };
Console.WriteLine(person.ToString());

output:

常用工具Utils

using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApp2
{//工具类class Utils{private static Utils instance = null;public static Utils Instance{get{if(instance == null){instance = new Utils();}return instance;}}//生成随机数private static Random random = new Random();public int RandomNum(int a, int b){return random.Next(a, b);}//打印数组的方法public static void PrintArray(int[] array){for (int i = 0; i < array.Length; i++){Console.WriteLine(array[i]);}}public static void PrintArray(int[,] array){for (int i = 0; i < array.GetLength(0); i++){for (int j = 0; j < array.GetLength(1); j++){Console.WriteLine(array[i, j]);}}}}
}

调用

Utils.Instance.RandomNum(1,100);

范例

题目

我的解答


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace mhls
{class CharacterManager{private static CharacterManager instance = null;public static CharacterManager Instance{get{if (instance == null){instance = new CharacterManager();}return instance;}}Character[] all = new Character[100];int index = 0;public Character CreateCharacter(string name, int hp, int attack, int def){Character c = new Character(name, hp, attack, def);all[index] = c;index++;return c;}public void PrintAll(){for (int i = 0; i < index; i++){Character c = all[i];Console.WriteLine(all[i]);}}}class Character{public string name;//用属性可以简单实现只读属性public int attack { get; set; }public int def;public int hp;public Character(){name = "未知";}public Character(string name, int hp, int attack, int def){this.name = name;this.hp = hp;this.attack = attack;this.def = def;}public void CostHp(int cost){this.hp -= cost;if (this.hp <= 0){this.hp = 0;}}public bool IsDead(){return hp <= 0;}public override string ToString(){return $"角色:{name} HP:{hp} 攻击力:{attack} 防御力:{def}";}}class Program{static void Main(string[] args){Character c1 = CharacterManager.Instance.CreateCharacter("男拳", 100, 15, 1);Character c2 = CharacterManager.Instance.CreateCharacter("女拳", 70, 10, 10);CharacterManager.Instance.PrintAll();Console.WriteLine();//战斗过程while (!c1.IsDead() && !c2.IsDead()){if (c1.hp > 20){int cost1 = c1.attack - c2.def;c2.CostHp(cost1);Console.WriteLine($"{c1.name}攻击了{c2.name},{c2.name}损失了{cost1}血量");Console.WriteLine(c1);Console.WriteLine(c2);Console.WriteLine();}else{Console.WriteLine("男拳血量少于20,触发愤怒被动,攻击力翻倍");int cost2 = 2 * c1.attack - c2.def;c2.CostHp(cost2);Console.WriteLine($"{c1.name}攻击了{c2.name},{c2.name}损失了{cost2}血量");Console.WriteLine(c1);Console.WriteLine(c2);Console.WriteLine();}if (c2.IsDead()){break;}int cost = c2.attack - c1.def;c1.CostHp(cost);Console.WriteLine($"{c2.name}攻击了{c1.name},{c1.name}损失了{cost}血量");Console.WriteLine(c1);Console.WriteLine(c2);Console.WriteLine();}//判断胜负if (c1.IsDead()){Console.WriteLine($"------{c2.name}胜利!------");Console.WriteLine();}else{Console.WriteLine("女拳第一次死亡,触发复活被动,复活30滴血,继续战斗");Character c3 = CharacterManager.Instance.CreateCharacter("女拳", 30, 10, 10);Console.WriteLine(c1);Console.WriteLine(c3);Console.WriteLine();while (!c1.IsDead() && !c3.IsDead()){if (c1.hp > 20){int cost3 = c1.attack - c3.def;c3.CostHp(cost3);Console.WriteLine($"{c1.name}攻击了{c3.name},{c3.name}损失了{cost3}血量");Console.WriteLine(c1);Console.WriteLine(c3);Console.WriteLine();}else{Console.WriteLine("男拳血量少于20,触发愤怒被动,攻击力翻倍");int cost4 = 2 * c1.attack - c3.def;c3.CostHp(cost4);Console.WriteLine($"{c1.name}攻击了{c3.name},{c3.name}损失了{cost4}血量");Console.WriteLine(c1);Console.WriteLine(c3);Console.WriteLine();}if (c3.IsDead()){break;}int cost5 = c3.attack - c1.def;c1.CostHp(cost5);Console.WriteLine($"{c3.name}攻击了{c1.name},{c1.name}损失了{cost5}血量");Console.WriteLine(c1);Console.WriteLine(c3);Console.WriteLine();}if (c1.IsDead()){Console.WriteLine($"------{c3.name}胜利!------");Console.WriteLine();}else{Console.WriteLine($"------{c1.name}胜利!------");}Console.ReadKey();}}}
}

题目


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace shuihu
{class Shuihu{public string name;public int capacity;public int water { get; set; }public int temperature;public Shuihu(string name,int capacity,int water,int temperature){this.name = name;this.capacity = capacity;this.water = water;this.temperature = temperature;}public void addwater(int a){if(a<(this.capacity- this.water)){this.water += a;Console.WriteLine($"添加{a}毫升的水");Console.WriteLine();}else{int y = (this.water + a - this.capacity);this.water = this.capacity;  Console.WriteLine($"添加{a}毫升的水");Console.WriteLine("水已注满,溢出" + y + "毫升");Console.WriteLine();}}public void pumpwater(int a){if (a < this.water){this.water -= a;Console.WriteLine($"抽出{a}毫升的水");Console.WriteLine();}else{this.water = 0;Console.WriteLine($"杯子已经空了");Console.WriteLine();}}public void heatwater(int a){if(this.water != 0){if (a > this.temperature && a < 100){this.temperature = a;Console.WriteLine($"水温已加热至{a}摄氏度");Console.WriteLine();}else if (a < this.temperature){Console.WriteLine($"当前水温为{this.temperature}摄氏度,无法降温");Console.WriteLine();}else{Console.WriteLine($"水温最多加至100摄氏度,当前水温为{this.temperature}摄氏度");Console.WriteLine();}}else{Console.WriteLine("被子里面没有水,无法加热");}}public override string ToString(){return $"{name} 容量{capacity} 水量{water} 温度{temperature}";}}class Program{static void Main(string[] args){Shuihu H1 = new Shuihu("小茶杯",100,0,30);Console.WriteLine("水杯初始状态");Console.WriteLine(H1.ToString());Console.WriteLine();Console.WriteLine($"请输入加水量____毫升");int add = int.Parse(Console.ReadLine());H1.addwater(add);Console.WriteLine(H1.ToString());Console.WriteLine();Console.WriteLine($"请输入抽水量____毫升");int sub = int.Parse(Console.ReadLine());H1.pumpwater(sub);Console.WriteLine(H1.ToString());Console.WriteLine();Console.WriteLine($"请输入目标温度____");int tem = int.Parse(Console.ReadLine());H1.heatwater(tem);Console.WriteLine(H1.ToString());Console.WriteLine();}}
}

【学习日志】2022.08.26 C#单例模式 Tostring Utils相关推荐

  1. 【记录ROS学习(五)2022/08/27】Win版ROS/Noetic 如何添加必要的依赖(rosdep)

    [记录ROS学习(五)2022/08/27]Win版ROS/Noetic 如何添加必要的依赖(rosdep) 近期为了使得更多的设备可以连入ROS,开始转向Windows平台的ROS,遇到一些问题 无 ...

  2. java 学习笔记2022.1.26

    排序 Comparator接口 有关于Comparator接口,这个接口一般是作为参数放在排序方法里的,最开始我也觉得挺别扭的,后面想了想,这也主要是因为在java中,单独的一个函数不能存在,所以设计 ...

  3. 学习日志——2019/08/05

    事务& 数据连接池& DBUtils 事务 什么是事务? Transaction 其实指的一组操作,里面包含许多个单一的逻辑.只要有一个逻辑没有执行成功,那么都算失败. 所有的数据都回 ...

  4. 数学建模学习视频及资料集(2022.08.10)

    2021高中数学建模(应用)能力展示活动细则详解(上) 2021高中数学建模(应用)能力展示活动细则详解(上)_哔哩哔哩_bilibili 2021高中数学建模(应用)能力展示活动细则详解(下) 20 ...

  5. Hibiscus的脑机接口学习周报(2022/12/26~2022/1/1)

    2022/12/26(星期一) 在学习使用python mne库读取.set类型数据时,遇到了类似如下报错:buffer is too small (来源于Python读取.set格式的脑电数据出现b ...

  6. Python学习日志08 - 字典

    Python学习日志 RBHGO的主页欢迎关注 温馨提示:创作不易,如有转载,注明出处,感谢配合~ 目录 文章目录 Python学习日志 目录 Python学习日志08课 - 字典 前言 进入正题 创 ...

  7. 个人学习OpenCV开源机器视觉准备如下2022.11.26

    个人学习OpenCV开源机器视觉准备如下2022.11.26: 我学AI,先安装VS,这里安装了VS2022专业版 再下载OpenCV的(2022-06-12)opencv-4.6.0-vc14_vc ...

  8. 苏嵌学习日志08 07.16

    学习日志 刘易中 07.16 今日学习任务 C51单片机的基本常识.LED灯.蜂鸣器.普通按键.矩阵按键 今日任务完成情况 复习了C51单片机的理论知识,介绍了LED灯.蜂鸣器.按键的简单编程和仿真 ...

  9. 2022/7/26华为机试,Q2,上机迷迷糊糊的,搞完突然醒悟,自抱自泣!三道题附带答案

    21:52 2022/7/26华为机试三道题附带答案 备注:未ac,华为不难,难的是个人很难进入答题状态! 第一道 给定一个字符串,是工作记录的日志时间,时间为四段格式,AA:BB:CC:DDD 其中 ...

最新文章

  1. 4.Windows下安装ZooKeeper
  2. stm32如何执行软复位_常见的单片机复位方式及其原理分析
  3. 局部特征用于图像检索 Aggregating local features for Image Retrieval
  4. java加载并运行虚拟机_《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?...
  5. Web服務器的配置方法
  6. 下一个更大元素 leetcode-496
  7. word-break 对一个字符串根据给出的字典判断是否可以根据字典切分(DP问题)
  8. openLayer加载KML,画出省及省下的边界区域,并设置样式、各种标注及提示信息
  9. 在windows平台下搭建Django项目虚拟环境
  10. 音乐 美术 劳技 计算机教研组工作总结,美术劳技室工作总结
  11. STM32标准库官网下载方法
  12. Hadoop大数据之Debug
  13. 如何在集合中巧用Where来查找相关元素
  14. vue cli3.0 解决跨域问题和axios等问题,配合Django
  15. DXperience Winforms12.2版中文使用手册
  16. Android手机通讯录制作
  17. 时空召唤服务器维护2020,2020年11月24日定期维护解读
  18. html5标签思维导图,HTML/HTML5 知识点思维导图
  19. android 快速关闭键盘的方法,安卓永久关闭键盘灯的方法
  20. 「Python条件结构」显示学号及提示信息

热门文章

  1. 计算机单片机考试作弊检讨书,关于大学生考试作弊检讨书1000字范文[共7页]
  2. PS室内植物素材合成教程分享骞
  3. 目标管理【管理学之十四】
  4. Linux Miscellaneous Device
  5. Google Earth谷歌地球卫片下载器--可下载全球历史卫星,无偏移、高精度
  6. angular ts 表格_Angular8 ui-grid替代方案ag-grid入门
  7. UE4中英文语言切换的三种方式(当然也可以多种语言)
  8. Java实现bt文件下载、制作、解析、磁力链接
  9. 苹果手机wifi很慢解决方法
  10. 复古汉字_30个时髦的WordPress复古主题