- 博客(58)
- 收藏
- 关注
原创 C# 经典实例 第三章 数据类型 #3.6 舍入浮点值
问题:你需要将一个数字舍入位一个整数,或者舍入到指定的小数点位数。解决方案:要将一个数字舍入为其最接近的整数,可以使用静态方法Math.Round方法,该方法只接受一个参数:int i = (int)Math.Round(2.5555); // i == 3如果你需要将一个浮点值舍入到指定的小数点位数,可使用重载的Math.Round方法,他接受两个参数:double dbl = Math.Round(2.5555, 2); // dbl == 2.56讨论:Round方法.
2020-09-23 17:00:59
266
原创 C# 经典实例 第三章 数据类型 #3.5 确定一个字符串是否为有效的数字
问题:你有一个可能包含一个数字值的字符串,你需要知道该字符串是否包含了一个有效的数字。解决方案:使用任意数字类型的静态TryParse方法。例如,要确定一个字符串是否包含一个double,可使用下列方法。 string str = "12.5"; double result = 0; if (double.TryParse(str, System.Globalization.Num
2020-09-23 16:52:34
326
原创 C# 经典实例 第三章 数据类型 #3.4 把字符串传递给只接受byte[]的方法
问题:FCL中的许多方法接受由字符构成的byte[],而不是string。下面是其中的一些方法: System.Diagnostics.EventLog.WriteEntry System.IO.BinaryWriter.Write System.IO.FileStream.Write System.IO.FileStream.BeginWrite System.IO.MemoryStream.Write System.IO.MemorySt
2020-09-23 16:48:12
321
原创 C# 经典实例 第三章 数据类型 #3.3 把作为byte[]返回的字符串转换为字符串
问题:FCL中的许多方法都返回一个byte[],因为他们都提供了一种字节流服务,但是一些应用程序需要通过这些字节流传递字符串。下面是其中的一些方法。 System.Diagnostics.EventLogEntry.Data System.IO.BinaryReader.Read System.IO.BinaryReader.ReadBytes System.IO.FileStream.Read System.IO.FileStream.BeginRead
2020-09-23 16:26:19
303
原创 C# 经典实例 第三章 数据类型 #3.2 解码base64编码的二进制数据
问题:你有一个String,其中包含编码为base64的信息,例如一个位图。你需要把此数据(它可能嵌入在电子邮件消息中)从String解码为byte[],以便访问原始的二进制数据。解决方案:使用Convert类的静态方法Convert。FromBase64String,可以将编码String解码为其对应的byte[]。 public static byte[] Base64DecodeString(this string inputStr) { by
2020-09-23 16:09:34
362
原创 C# 经典实例 第三章 数据类型 #3.1 把二进制数据编码为base64格式
问题:你有一个byte[]用于表示一些二进制信息,比如位图。你需要把该数据编码为一个字符串,以便可以通过不适合传输二进制的方式(比如电子邮件)发送它。解决方案:使用Convert类的静态方法Convert.ToBase64String,可以把byte[]编码为其对应的String。 static class DataTypeExtMethods { public static string Base64EncodeBytes(this byte[] inputByt
2020-09-23 15:59:11
432
原创 C# 经典实例 第三章 数据类型 简介
简介:作为一种值类型,简单类型(simple type)是C#中内建类型的一个子集,不过事实上这些类型被定义为.NET Framework类库(.NET FCL)的一部分。简单类型由若干数字类型和一个bool类型构成。这些数字类型包括一个十进制类型(decimal)、九个整数类型(byte、char、int、long、sbyte、short、unit、ulong、和ushort)以及两个浮点类型(float和doubule)。表3-1列出了.NET Framework中的简单类型及其完全限定名。表3
2020-09-23 15:30:30
211
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.10 使用线程安全的字典进行并发访问,不手动加锁
问题:你需要创建一个从多个线程中并发读写的键值对的集合,并且不需要手动使用同步原语来保护它。解决方案:使用ConcurrentDictionary<Tkey,TValue>容纳数据项并线程安全的方式来访问它们。举例来说,考虑一个模拟情形,球迷到一个体育馆去观看他们喜爱的体育赛事,并且场馆仅有若干个入口。首先,我们需要一些球迷并且记录他们的名称、何时入场以及通过哪个入口入场。 public class Fan { public s
2020-09-23 10:52:40
256
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.9 在类中实现嵌套的foreach功能
问题:你需要一个类,它包含一个对象列表,其中每个对象也包含一个对象列表。你希望以如下方式使用嵌套的foreach循环遍历外层和内层列表中的所有对象。foreach (Group<Item> subGroup in topLevelGroup){ // 操作组 foreach (Item item in subGroup) { // 操作数据项 }}解决方案:在类上实现IEnumerable<
2020-09-23 10:16:42
282
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.8 处理finally语句块和迭代器
问题:你向迭代器中添加了一个try-finally语句块,并且注意到finally块并没有按所想的那样执行。解决方案:在GetEnumerator迭代器中用一个try块包围迭代代码,并在该try块后接一个finally块,代码如下所示: public static void TestFinallyAndIterators() { //Create a StringSet object and fill it with data
2020-09-22 16:48:19
223
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.7 创建自定义枚举器
问题:你需要向一个类中添加foreach支持,但是通常永固添加迭代器的方式(即在类型上实现IEnumerable并从一个成员函数返回执行这个IEnumerable的引用)并不足够灵活。除了简单的从第一个元素迭代到最后一个元素之外,还需要从最后一个元素迭代到第一个元素,并且需要能够在每次迭代时跨越或跳过预定义数量的元素。你想使所有这些类型的迭代器可供你的类使用。解决方案:例2-4中所示的Container<T>类充当一个名为internalList的私有List<T>的容器
2020-09-22 11:56:21
235
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.6 测试Array或List<T>中的每个元素
问题:你需要采用一种容易的方法来测试Array或List<T>中的每个元素。这种测试的结果应该指示集合中的所有元素都通过了测试,或者集合中至少有一个元素没有通过测试。解决方案:使用TrueForAll方法,代码如下所示: public static void TestArrayForNulls() { // Create a List of strings List<string> strings =
2020-09-22 11:21:30
165
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.5 在应用程序会话间持久化一个集合
问题:你有一个诸如ArrayList、List<T>、Hashtable或者Dictionary<T,U>这样的集合,在其中存储应用程序信息。可以使用该信息将应用程序的环境定制成最后一只的设置(例如,窗口大小,窗口位置和当前显示的工具栏)。也可以用它来允许用户在上一次关闭应用程序的相同位置启动应用程序。换句话说,如果用户正在编辑发票并且需要在晚上关闭计算机,当下次启动应用程序时,它将准确的知道初始化要显示哪张发票。解决方案:在对象与文件之间进行序列化/反序列化。
2020-09-22 11:07:45
125
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.4 创建具有最小值和最大值边界的Dictionary
问题:你需要在项目中使用一个泛型Dictionary对象,它在值中仅存储预定义最大值和最小值之间的数值数据(键可以是任意类型)。解决方案:创建一个类,它带有强制执行这些边界的访问器和方法。例2-2中所示的类MinMaxValueDictionary只允许存储实现了IComparable接口的类型,并且其值位于最大值和最小值之间。例2-2:创建具有最小值和最大值边界的字典: [Serializable] public class MinMaxValueDi
2020-09-22 10:49:32
251
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.3 对Dictionary的键和/或值排序
问题:你想要对一个Dictionary中包含的键和/或值排序,以便把整个Dictionary显示给用户,并以升序或降序方式对它进行排序。解决方案:通过LINQ查询以及Dictionary<T,U>对象的Keys和Values属性,获得其键和值对象的有序ICollection.下面所示的代码显示以升序或降序排序的Dictionary<T,U>的键和值。 public static void TestSortKeyValues() {
2020-09-22 10:39:43
184
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.2 保持List<T>有序
问题:你将使用List<T>的BinarySearch方法定期查找List<T>中的特定元素。在查找过程中,将穿插进行添加、修改和删除的操作。不过,BinarySearch方法预先假设数组是有序的。如果List<T>是无序的,BinarySearch方法可能返回不正确的结果。你不希望必须记住在调用List<T>.BinarySearch方法之前调用List<T>.Sort方法。更不必说会引入与该调用关联的所有开销。你需要采用一种方法保持List
2020-09-22 10:27:14
167
原创 C# 经典实例 第二章 集合、枚举器和迭代器 #2.1 寻找List<T>中的重复数据项
问题:你需要能够对一个List<T>中匹配搜索条件的对象进行读取或计数操作。解决方案:使用List<T>的四个扩展方法:GetAll,BinarySearchGetAll、CountAll和BinarySearchCountAll。这些方法扩展List<T>类,以返回特定的对象实例或特定对象出现在有序和无序List<T>中的次数,如例2-1所示。例2-1:确定一个数据项在List<T>中出现的次数 static class
2020-09-22 10:02:10
299
原创 C# 经典实例 第二章 集合、枚举器和迭代器 简介
简介集合是一组数据项;在.NET中,集合包含对象,而包含在集合中的每个对象被称为元素(element)。有些集合包含简单的元素列表,而另外一些集合[比如字典(dictionary)]则包含键值对的列表。下列集合类型包含简单的元素列表: System.Collections.ArrayList System.Collections.BitArray System.Collections.Queue System.Collections.Stack System
2020-09-22 09:31:21
173
原创 C# 经典实例 第一章 类和泛型 #1.19 以更简洁的方式检查null值
问题:你不断地编写笨拙的if-then 语句来判断一个对象是否为null。你需要一种更简洁、更简单的方式来编写这类代码。解决方案:使用C# 6.0 中新引入的null 条件运算符。在过去,通常需要在使用对象前进行检查以确保对象不为null。if (val != null){ val.Trim().ToUpper(); ... }现在你可以简单地使用null 条件运算符。val?.Trim().ToUpper(); 这一简化的语法判断val 是否为null
2020-09-21 08:44:58
235
原创 C# 经典实例 第一章 类和泛型 #1.18 控制结构类型字段初始化
问题:你需要能够控制结构的初始化,取决于是否想要将结构的所有内部字段初始化为基于字段类型的标准默认值(例如,int 初始化为0,string 初始化为空字符串),或者初始化为一组非标准的默认值,或者初始化为一组预定义的值。解决方案:可以使用结构的各种构造函数来实现我们的目标。要将结构的所有内部字段初始化为基于字段类型的标准默认值,只需使用结构的默认初始化即可,稍后会演示这一点。要将结构的字段初始化为一组预定义的值,可以使用重载的构造函数。最后,要将结构初始化为一组非标准的默认值,需要在结构构造函
2020-09-21 08:44:05
235
原创 C# 经典实例 第一章 类和泛型 #1.17 使用函数对象在列表中执行多种操作
问题:你希望能够同时对整个对象集合执行多种操作,并在功能上隔离这些操作。解决方案:使用函数对象(functor或function object)作为转换集合的工具。函数对象是任何一个可以作为函数被调用的对象。例如,委托函数、函数指针,甚至是C/C++中定义了operator()的对象。在软件中,经常需要对一个集合执行多种操作。假定你的股票组合包含了一系列股票。StockPortfolio类包含一个Stock对象的List,并且能够添加股票。public class StockPor
2020-09-21 08:43:38
262
原创 C# 经典实例 第一章 类和泛型 #1.16 在C#中使用闭包
问题:你希望把少量状态与某种行为关联起来,但不会陷入构建新类的麻烦之中。解决方案:使用lambda 表达式实现闭包。闭包是声明时捕获作用域中环境状态的函数。简单地讲,它们是当前状态以及某种可以读取和修改该状态的行为。lambda 表达式能够捕获外部变量并延长它们的生存期,这使得闭包可以在C# 中使用。关于lambda 表达式的更多信息,请参考4.0 节。作为闭包的一个示例,我们将构建一个快速报告系统,用于跟踪销售人员及其收益和佣金。闭包的行为是,你可以构建一些代码,用于计算每个季度的佣金
2020-09-21 08:43:19
155
原创 C# 经典实例 第一章 类和泛型 #1.15 控制如何触发多播委托中的一个委托
问题:你组合了多个委托来创建一个多播委托。当调用这个多播委托时,将依次调用其中的每个委托。你需要施加更多的控制。例如,调用每个委托的顺序,只触发一个委托子集或者基于前一个委托成功与否来触发每个委托。此外,你需要能够单独处理每个委托的返回值。解决方案:使用GetInvocationList 方法获得Delegate 对象的数组。接下来,使用for 循环(如果以非标准顺序进行枚举)或foreach 循环(如果以标准顺序进行枚举)遍历这个数组。然后可以逐个调用数组中的每个Delegate 对象,并且
2020-09-18 14:09:52
213
原创 C# 经典实例 第一章 类和泛型 #1.14 向生成的实体中添加钩子
问题:你有一种生成分部类业务实体定义的过程,并且想添加一种轻量级的通知机制。解决方案:使用分部方法在生成的代码中为业务实体添加钩子。生成实体的过程可能来自于UML、数据集或者其他对象建模工具,但是当代码被生成为分部类时,为调用ChangingProperty 分部方法的属性会将分部方法挂钩添加到模板中,如GeneratedEntity 类中所示。public partial class GeneratedEntity{ public GeneratedEntity(str
2020-09-18 13:59:26
150
原创 C# 经典实例 第一章 类和泛型 #1.13 将泛型变量初始化为默认值
问题:你有一个泛型类,它包含一个变量,其类型与类自身定义的类型参数的类型相同。在构造泛型对象时,你希望将该变量初始化为它的默认值。解决方案:简单地使用default 关键字将该变量初始化为它的默认值。public class DefaultValueExample<T>{ T data = default(T); public bool IsDefaultData() { T temp = default(T); if
2020-09-18 13:54:25
798
原创 C# 经典实例 第一章 类和泛型 #1.12 约束类型参数
问题:你需要用一种类型参数来创建泛型类型,该类型参数必须支持特定接口的成员,如IDisposable。解决方案:使用约束条件强制要求泛型类型的类型参数是一种实现一个或多个特定接口的类型。public class DisposableList<T> : IList<T>where T : class, IDisposable{ private List<T> _items = new List<T>(); // 私有方法,处
2020-09-18 13:50:34
183
原创 C# 经典实例 第一章 类和泛型 #1.11 反转有序列表汇总的内容
问题:你希望能够反转数据项的有序列表中的内容,并且还能够同时以数组和列表方式访问它们,就像使用SortedList 和泛型类 SortedList<T> 那样。SortedList 和SortedList<T> 都没有提供除重加载列表之外完成该任务的直接方式。解决方案:使用LINQ to Object查询SortedList<T>,并对列表中的信息应用降序排序。在实例化一个键为int、值为string的SortedList<TKey,TValue>
2020-09-18 13:44:03
141
原创 C# 经典实例 第一章 类和泛型 #1.10 理解泛型类型
问题:你需要理解.NET 类型如何适用于泛型,以及泛型.NET 类型与常规.NET 类型有着怎样的区别。解决方案:可以用两个快速的试验来展示常规.NET 类型和泛型.NET 类型之间的区别。在深入代码之前,如果你对泛型不熟悉,可以先跳到具体解释泛型的1.10.3 节,之后再回到本部分。当定义一个常规.NET 类型时,它看起来就像是例1-6 中定义的FixedSizeCollection 类型。例1-6:FixedSizeCollection(一种常规.NET 类型)public c
2020-09-18 10:05:59
181
原创 C# 经典实例 第一章 类和泛型 #1.9 确定何时何处使用泛型
问题:你想在新项目中使用泛型类型或者把现有项目中的非泛型类型转换成它们对应的泛型类型。不过,你并不真正明白为什么要这样做,也不知道应该把哪些非泛型类型转换成泛型类型。解决方案:在决定何时何处使用泛型类型时,需要考虑以下几点。你的类型将包含或操作多种不同的未确定数据类型(例如,一种集合类型)吗?如果是,那么与创建非泛型类型相比,创建泛型类型会有几个好处。如果你的类型只操作某种特定的类型,那么可能不需要创建泛型类型。如果你的类型在值类型上操作,那么将会发生装箱和拆箱操作。你应该考虑使用泛型来
2020-09-18 09:59:19
154
原创 C# 经典实例 第一章 类和泛型 #1.8 确保对象的处置
问题:当一个对象的工作完成或者超出作用域时,你需要采用一种方式确保一些处理得到执行。解决方案:使用using 语句,代码如下所示。using System;using System.IO;// ... using (FileStream FS = new FileStream("Test.txt", FileMode.Create)){ FS.WriteByte((byte)1); FS.WriteByte((byte)2); FS.WriteByte((
2020-09-18 09:57:17
122
原创 C# 经典实例 第一章 类和泛型 #1.7 构建可克隆的类
问题:你需要一种方法对可能引用其他类型的数据类型进行浅克隆操作、深克隆操作或者同时执行这两种操作,但是不应该使用ICloneable接口,因为它违反了.NET Framework设计准则。解决方案:为了解决使用ICloneable 的问题,创建另外两个接口IShallowCopy<T> 和IDeepCopy<T> 来建立一种复制模式,代码如下所示。public interface IShallowCopy<T> { T ShallowCopy();
2020-09-18 09:51:15
204
原创 C# 经典实例 第一章 类和泛型 #1.6 在运行时初始化常量字段
问题:标记为const的字段只能在编译时初始化。你需要在运行时而不是在编译时将一个字段初始化为一个有效值。然后在应用程序剩余的生命周期内,这个字段必须像一个常量字段那样工作。解决方案:在代码中声明一个常量时有两种选择。可以使用readonly字段或const字段,每种方式都有优缺点。不过,如果你需要在运行时初始化一个常量字段,就必须使用readonly字段。 public class Foo { public readonly int b...
2020-09-18 09:13:26
168
原创 C# 经典实例 第一章 类和泛型 #1.5 解析命令行参数
问题:需要应用程序以标准格式(在1.5.3中介绍)接受一个或多个命令行参数。你需要访问和解析传递给应用程序的完整的命令行。解决方案:在例1-5中,结合使用以下类来帮助解析命令行参数:Argument\ArgumentDefinition和ArgumentSemanticAnalyzer。例1-5:Argument类:using System;using System.Diagnostics;using System.Linq;using System.Collections.Ob
2020-09-17 16:14:24
344
原创 C# 经典实例 第一章 类和泛型 #1.4 从一个方法返回多个数据项
问题:在许多情况下,从一个方法返回一个值是不够的。你需要一种方式来从一个方法返回不止一个数据项。解决方案:1、对充当返回参数的参数使用关键字out。下面的方法接受一个InputShape参数,并通过该值计算height、width和depth public void ReturnDimensions(int inputShape, out int height, out int width, out int depth) { height = 0; width...
2020-09-17 15:01:57
262
原创 C# 经典实例 第一章 类和泛型 #1.3 使类型可查找
问题:有一种数据类型,它将存储为List<T>中的元素。你想使用BinarySearch方法,自定义你的数据类型在列表中的查找方式。解决方案:使用IComparable<T>和IComparer<T>接口。范例1.2(即1.2节)中的Square类实现了IComparable<T>接口,使得List<T>和SortedList<K,V>集合可以排序和查找Square对象的数组和集合。讨论:通过在类(或结构)上实现IC
2020-09-17 14:37:54
202
原创 C# 经典实例 第一章 类和泛型 #1.2 使类型可排序
问题:有一种数据类型,它将存储为List<T>或SortedList<K,V>的元素。你想使用List<T>.Sort方法或者SortedList<K,V>的内部排序机制来自定义此数据类型在数组中的排序方式。此外,你可能需要在SortedList集合中使用这种类型。解决方案:例1-1演示了如何实现IComparable<T>接口。例1-1中展示的Square类实现了这个接口,使得List<T>和SortedList<K
2020-09-17 14:18:38
157
原创 C# 经典实例 第一章 类和泛型 #1.1 创建联合类型的结构
问题:需要创建一种数据类型,其行为方式类似于C++中的联合类型。联合类型主要用于互操作场景,其中非托管代码接受和/或返回一个联合类型。(建议不要在其他情况下使用它)解决方案:使用一个结构,并用StructLayout特性标记他(在构造函数中指定LayoutKind.Explicit布局类型)。此外,利用FieldOffset特性标记结构中的每个字段。下面的结构定义了一个联合类型,其中可以存储一个带符号数值。using System.Runtime.InteropServices;[
2020-09-17 13:50:12
518
原创 C# 经典实例 第一章 简介
类比结构灵活得多。结构可以跟类一样实现接口,但与类不同的是,他们不能继承自类或结构。这种限制使得你无法创建结构层次关系,而这用类可以做到。通过抽象基类实现的多态性也是在结构中无法使用的,因为除了装箱成Object、ValueType和Enum,结构无法从另一个类派生。结构与其他值类型一样,都是从System.ValueType隐式派生的。结构类似于类,但实际上有很大的差别。在设计应用程序时,知道何时使用结构优于使用类将有很大的帮助。不正确的使用结构可能使代码性能低下、难以修改。结构相对于引用类型
2020-09-17 11:51:38
159
转载 XML序列化,动态修改特性元数据内容
通过为XML序列化添加XmlRootAttributeXmlRootAttribute root = new XmlRootAttribute();root.ElementName = "修改名称";XmlSerializer mySerializer =new XmlSerializer(typeof(Data), root);二、一般节点的ElementName的修改XmlElementAttribute myElementAttribute = new XmlElementAt..
2020-06-30 16:31:31
295
原创 WPF启动方式
1.窗体启动:WPF工程新建,默认启动方式为MainWindow窗体启动,程序直接以主窗体构造函数启动(F11启动程序可测试)。若想在启动前执行其他操作,可以对App.OnStartup进行重写。 修改App.xaml文件中StartupUri属性,可以修改启动窗体。2.代码启动在工程下新建启动操作类(Program),创建启动函数 static class Program { /// <summary> /// 应用程序的主...
2020-06-30 11:04:24
1053
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人