- .NET 指南
- 开始操作
- .NET 教程
- .NET 体系结构组件
- .NET Standard
- 什么是.NET 标准中的新增功能
- 目标框架
- .NET 术语表
- 使用 mdoc 生成文档
- .NET 的体系结构指南
- 使用 ASP.NET Core 和 Azure 构建新式 Web 应用程序
- 现代 Web 应用程序的特征
- 传统 Web 应用程序和单页面应用程序 (Spa) 之间进行选择
- 常见的客户端 Web 技术
- 开发 ASP.NET Core MVC 应用程序
- 使用 ASP.NET Core 应用中的数据
- 测试 ASP.NET Core MVC 应用程序
- Azure 的开发过程
- Azure 托管的 ASP.NET 核心 Web 应用的建议
- 使用 Azure 云和 Windows 容器更新现有 .NET 应用程序 (v1.0)
- 提升和移动现有应用 Azure IaaS
- 将关系数据库迁移到 azure
- 直接迁移现有应用 DevOps
- 到提起并移动现有的.NET 应用到云 DevOps 通用应用程序的原因
- 云 devops 通用应用程序中的 Microsoft 技术
- 云优化应用程序如何呢?
- 如何将现有的.NET 应用程序部署到 Azure App Service
- 将现有的.NET 应用程序部署为 Windows 容器
- 何时不将部署到 Windows 容器
- 何时在你的本地部署 Windows 容器 IaaS VM 基础结构
- 何时将 Windows 容器部署到 Azure Vm (IaaS 云)
- 何时到 Service Fabric 中部署 Windows 容器
- 何时将 Windows 容器部署到 Azure 容器服务 (即,Kubernetes)
- 构建可复原的服务供云: 采用在云中的暂时性故障
- 更新你的应用的监视和遥测
- 更新使用 CI/CD 管道和 DevOps 工具在云中的应用程序的生命周期
- 将迁移到混合云方案
- 演练和技术获取启动的概述
- 技术演练列表
- 技术演练列表
- 结论
- 容器和 Docker 简介
- 什么是 Docker?
- Docker 术语
- Docker 容器、 图像和注册表
- Docker 应用程序生命周期的介绍
- DevOps 协作基础的容器
- 有关适用于容器化应用的 Microsoft 平台和工具的简介
- 使用 Docker 和 Microsoft Azure 设计和开发容器化应用
- Docker 应用程序设计
- 常见容器设计原则
- 整体应用程序
- 状态和 Docker 应用程序中的数据
- SOA 应用程序
- 协调微服务和以高可伸缩性和可用性的 multicontainer 应用程序
- Docker 应用的开发环境
- 对于 Docker 应用程序的内部循环开发工作流
- 使用 Visual Studio Tools for Docker (在 Windows 上的 Visual Studio)
- 使用在 DockerFile 中的 Windows PowerShell 命令来设置 Windows 容器 (Docker 标准基于)
- 使用 Microsoft 工具的 Docker 应用程序 DevOps 工作流
- Docker 应用程序的外部循环 DevOps 工作流中的步骤
- 运行、管理和监视 Docker 生产环境
- 在生产环境中运行由和基于微服务的应用程序
- 管理生产 Docker 环境
- 监视容器化应用程序服务
- 关键结论
- .NET 微服务。 适用于容器化 .NET 应用程序的体系结构
- .NET 微服务。 适用于容器化 .NET 应用程序的体系结构
- 容器和 Docker 简介
- 什么是 Docker?
- Docker 术语
- Docker 容器、 图像和注册表
- 为 Docker 容器选择 .NET Core 还是 .NET Framework
- 一般性指导原则
- 何时选择 Docker 容器中的.NET 核心
- 何时选择 Docker 容器中的.NET Framework
- 决策表:.NET 框架,用于 Docker
- .NET 容器定向到何种操作系统
- 正式.NET Docker 映像
- 构建基于容器和微服务的应用程序
- Containerizing 整体应用程序
- 状态和 Docker 应用程序中的数据
- 面向服务的体系结构
- 微服务体系结构
- 每个微服务构成的数据自主性
- 与物理体系结构的逻辑体系结构
- 分布式的数据管理挑战和解决方案
- 标识每个微服务的域模型边界
- 直接与 API 网关模式的微服务构成客户端通信
- 在微服务体系结构的通信
- 基于消息的异步通信
- 创建、 不断发展,和版本控制 microservice Api 和协定
- 微服务可寻址性和服务注册表
- 创建复合 UI 基于微服务,包括 visual UI 形状和布局由多个微服务生成
- 复原和微服务中的高可用性
- 协调微服务和多容器应用程序的高可伸缩性和可用性
- 使用 Azure Service Fabric
- 基于 Docker 的应用程序的开发流程
- Docker 应用的开发工作流
- 在 Linux 或 Windows Nano Server 主机上部署基于单容器的 .NET Core Web 应用
- 将旧版整体式 .NET Framework 应用程序迁移到 Windows 容器
- 设计和开发基于微服务的多容器 .NET 应用程序
- 设计面向微服务构成的应用程序
- 创建简单的数据驱动 CRUD 微服务
- 定义与 docker-compose.yml 多容器应用程序
- 使用运行的容器的数据库服务器
- 实现基于事件的微服务 (集成事件) 之间的通信
- 实现使用 RabbitMQ 开发或测试环境事件总线
- 订阅事件
- 测试 ASP.NET 核心服务和 web 应用
- 使用 DDD 和 CQRS 模式降低微服务中的业务复杂性
- 应用中的微服务构成的简化的 CQRS 和 DDD 模式
- EShopOnContainers DDD 微服务中的应用 CQRS 和 CQS 方法
- 在 CQRS 微服务中实现读取/查询
- 设计 DDD 面向微服务
- 设计 microservice 域模型
- 实现 microservice 域模型与.NET 核心
- Seedwork (可重用基类,这些类和接口,您的域模型)
- 实现值对象
- 使用枚举类,而不枚举类型
- 设计域模型层中的验证
- 客户端验证 (验证在表示层)
- 域事件: 设计和实现
- 设计基础结构持久性层
- 实现与实体框架核心基础结构持久性层
- 作为持久性基础结构使用 NoSQL 数据库
- 设计微服务应用程序层和 Web API
- 实现微服务应用程序层使用 Web API
- 实现具有恢复能力的应用程序
- 处理部分失败
- 用于处理部分失败的策略
- 实现重试使用指数退让
- 实现弹性 Entity Framework 核心 SQL 连接
- 实现自定义 HTTP 调用的重试使用指数退让
- 使用 Polly 和实施 HTTP 调用重试使用指数退让
- 实现断路器模式
- 运行状况监视
- 保护 .NET 微服务和 Web 应用程序
- 有关在.NET 微服务和 web 应用程序的授权
- 在开发过程中安全地存储应用程序机密
- 使用 Azure 密钥保管库在生产时保护机密
- 记住的要点
- 为服务器应用选择 .NET Core 或 .NET Framework
- 什么是 托管代码 ?
- Automatic Memory Management
- 公共语言运行时 (CLR)
- 语言独立性和与语言无关的组件
- 语言独立性和与语言无关的组件
- 框架库
- .NET Framework 类库概述
- 在 .NET 中使用基类型
- 常规类型系统
- .NET Framework 中的类型转换
- .NET 中的类型转换表
- .NET 中的格式化类型
- 标准数字格式字符串
- 自定义数字格式字符串
- 标准日期和时间格式字符串
- 自定义日期和时间格式字符串
- 标准 TimeSpan 格式字符串
- 自定义的 TimeSpan 格式字符串
- 枚举格式字符串
- 复合格式设置
- 执行格式设置操作
- 如何:用前导零填充数字
- 如何:从特定日期中提取星期几
- 如何:定义和使用自定义数值格式提供程序
- 如何:往返日期和时间值
- 如何:将用户在 Web 控件中输入的数值转换为数字
- 如何:向 Web 用户显示本地化的日期和时间信息
- 如何:显示日期和时间值中的毫秒
- 如何:用非公历日历显示日期
- 操作在.NET 中的字符串
- 在.NET 中使用字符串的最佳做法
- .NET 中的基本字符串操作
- 在.NET 中创建新的字符串
- 剪裁和移除从.NET 中的字符串的字符
- .NET 中的空白字符串
- 比较.NET 中的字符串
- 更改.NET 中的大小写
- 在.NET 中使用 StringBuilder 类
- 如何: 在.NET 中执行基本字符串操作
- .NET 正则表达式
- 正则表达式语言 - 快速参考
- 正则表达式中的字符转义
- 正则表达式中的字符类
- 正则表达式中的定位点
- 正则表达式中的分组构造
- 正则表达式中的限定符
- 正则表达式中的反向引用构造
- 正则表达式中的备用构造
- 正则表达式中的替代
- 正则表达式选项
- 正则表达式中的其他构造
- .NET 中的正则表达式的最佳实践
- 正则表达式对象模型
- 正则表达式行为的详细信息
- 正则表达式中的回溯
- 正则表达式中的编译和重复使用
- 正则表达式中的线程安全
- 正则表达式示例
- 正则表达式示例:扫描 HREF
- 正则表达式示例:更改日期格式
- 如何:从 URL 中提取协议和端口号
- 如何:从字符串中剥离无效字符
- 如何:确认字符串是有效的电子邮件格式
- 在.NET 中编码的字符
- 在.NET 中分析字符串
- NET 中分析数值字符串
- 分析日期和时间字符串.NET 中
- .NET 中分析其他字符串
- .NET 类库
- .NET 可移植性分析器
- 在 .NET 中处理和引发异常
- .NET 程序集文件格式
- 内存管理和.NET 中的垃圾回收
- 垃圾回收
- 垃圾回收的基础
- 垃圾回收和性能
- 被动回收
- 滞后时间模式
- 针对共享 Web 承载优化
- 垃圾回收通知
- 应用程序域资源监控
- 弱引用
- 泛型类型(泛型)概述
- 委托和 lambda
- LINQ(语言集成查询)
- 常规类型系统和公共语言规范
- 异步概述
- 深入了解异步
- 异步编程模式
- 基于任务的异步模式 (TAP)
- 实现基于任务的异步模式
- 使用基于任务的异步模式
- 与其他异步模式和类型互操作
- 基于事件的异步模式 (EAP)
- 使用基于事件的异步模式进行多线程编程
- 基于事件的异步模式概述
- 实现基于事件的异步模式
- 实现基于事件的异步模式的最佳做法
- 确定何时实现基于事件的异步模式
- 演练:实现支持基于事件的异步模式的组件
- 演练:实现支持基于事件的异步模式的组件
- 如何:实现基于事件的异步模式的客户端
- 如何:使用支持基于事件的异步模式的组件
- 异步编程模型 (APM)
- 使用 IAsyncResult 调用异步方法
- 使用 AsyncWaitHandle 阻止应用程序的执行
- 通过结束异步操作来阻止应用程序执行
- 轮询异步操作的状态
- 使用 AsyncCallback 委托结束异步操作
- 使用 AsyncCallback 委托和状态对象
- 使用委托进行异步编程
- 使用异步方式调用同步方法
- 本机互操作性
- 集合和数据结构
- .NET Framework 中的数字
- 日期、时间和时区
- 时区概述
- 在 DateTime、DateTimeOffset、TimeSpan 和 TimeZoneInfo 之间进行选择
- 查找本地系统上定义的时区
- 如何: 枚举计算机上存在的时区
- 如何: 访问预定义的 UTC 和当地时间区域对象
- 如何: 实例化 TimeZoneInfo 对象
- 实例化 DateTimeOffset 对象
- 如何: 创建不带调整规则的时区
- 如何: 创建带有调整规则的时区
- 保存和还原时区
- 如何: 将时区保存到嵌入的资源
- 如何: 从嵌入的资源还原时区
- 使用日历
- 使用日期和时间执行算术运算
- 如何: 在日期和时间运算中使用时区
- 在 DateTime 与 DateTimeOffset 之间进行转换
- 在各时区之间转换时间
- 如何: 解决不明确的时间
- 如何: 让用户解决不明确的时间
- 处理和引发事件
- 如何:引发和使用事件
- 如何:使用事件属性处理多个事件
- 如何:在 Web 窗体应用程序中使用事件
- 观察程序设计模式
- 观察程序设计模式最佳做法
- 如何:实现提供程序
- 如何:实现观察程序
- 托管执行过程
- 元数据和自描述组件
- 在 .NET Framework 中构建控制台应用程序
- .NET Framework 中的并行处理和并发
- .NET Framework 应用程序要点
- 文件和流 I/O
- 对 .NET Framework 应用程序进行全球化和本地化
- 全球化
- 本地化评审
- 本地化
- 不区分区域性的字符串操作
- 执行不区分区域性的字符串操作
- 执行不区分区域性的字符串比较
- 执行不区分区域性的大小写更改
- 在集合中执行不区分区域性的字符串操作
- 在数组中执行不区分区域性的字符串操作
- 开发全球通用应用程序的最佳做法
- 利用特性扩展元数据
- 应用特性
- 编写自定义特性
- 检索存储在特性中的信息
- 框架设计准则
- 命名准则
- 大小写约定
- 通用命名约定
- 程序集和 DLL 的名称
- 命名空间的名称
- 类、结构和接口的名称
- 类型成员的名称
- 命名参数
- 命名资源
- 类型设计准则
- 在类和结构之间选择
- 抽象类设计
- 静态类设计
- 接口设计
- 结构设计
- 枚举设计
- 嵌套类型
- 成员设计准则
- 成员重载
- 属性设计
- 构造函数设计
- 事件设计
- 字段设计
- 扩展方法
- 运算符重载
- 参数设计
- 扩展性设计
- 未密封类
- 受保护的成员
- 事件和回调
- 虚成员
- 抽象(抽象类型和接口)
- 用于实现抽象的基类
- 密封
- 异常设计准则
- 异常引发
- 使用标准异常类型
- 异常和性能
- 使用准则
- 数组
- 特性
- 集合准则
- 序列化
- System.Xml 使用情况
- 相等运算符
- 常见设计模式
- 依赖项属性
- 释放模式
- XML 文档和数据
- XML 处理选项
- 内存中 XML 数据处理
- 使用 DOM 模型处理 XML 数据
- XML 文档对象模型 (DOM)
- XML 节点类型
- XML 文档对象模型 (DOM) 层次结构
- 将对象层次结构映射到 XML 数据
- 创建 XML 文档
- 将 XML 文档读入 DOM
- 嵌入到文档中的样式表指令
- 从读取器中加载数据
- 加载 DOM 时的空白和有效空白处理
- 访问 DOM 中的属性
- 将实体声明和实体引用读入 DOM
- 保留实体引用
- 扩展但不保留实体引用
- 将节点插入 XML 文档中
- 在 DOM 中创建新节点
- 为 DOM 中的元素创建新属性
- 创建新节点时的 XML 元素和属性名验证
- 创建新实体引用
- 命名空间对包含元素和属性的新节点的实体引用扩展的影响
- 复制现有节点
- 将现有节点从一个文档复制到另一个文档
- 复制文档片段
- 移除 XML 文档中的节点、内容和值
- 从 DOM 中移除节点
- 移除 DOM 中元素节点的属性
- 移除 DOM 中的节点内容
- 修改 XML 文档中的节点、内容和值
- 在 DOM 中验证 XML 文档
- 保存和写出文档
- 使用 XPath 导航选择节点
- 解析外部资源
- 使用 XmlNameTable 的对象比较
- NamedNodeMap 和 NodeList 中的节点集合
- 按名称或索引检索未排序节点
- 按索引检索已排序节点
- NodeList 和 NamedNodeMap 的动态更新
- DOM 中的命名空间支持
- DOM 中的命名空间和 DTD
- 更改 XML 文档中的命名空间声明
- 更改命名空间前缀属性
- 使用 mlNodeChangedEventArgs 的 XML 文档中的事件处理
- 扩展 DOM
- 使用 XPath 数据模型处理 XML 数据
- 使用 XPathDocument 和 XmlDocument 读取 XML 数据
- 使用 XPathNavigator 选择、计算和匹配 XML 数据
- 使用 XPathNavigator 选择 XML 数据
- 使用 XPathNavigator 计算 XPath 表达式
- 使用 XPathNavigator 匹配节点
- XPath 查询识别的节点类型
- XPath 查询和命名空间
- 已编译的 XPath 表达式
- XPath 命名空间浏览
- 使用 XPathNavigator 访问 XML 数据
- 使用 XPathNavigator 的节点集定位
- 使用 XPathNavigator 的属性和命名空间节点定位
- 使用 XPathNavigator 提取 XML 数据
- 使用 XPathNavigator 访问强类型 XML 数据
- 用户定义的函数和变量
- 使用 XPathNavigator 编辑 XML 数据
- 使用 XPathNavigator 插入 XML 数据
- 使用 XPathNavigator 修改 XML 数据
- 使用 XPathNavigator 移除 XML 数据
- 使用 XPathNavigator 验证架构
- 使用 LINQ to XML 处理 XML 数据
- XSLT 转换
- 使用 XslCompiledTransform 类
- XslCompiledTransform 类的输入
- XslCompiledTransform 类的输出选项
- 在 XSLT 处理期间解析外部资源
- 扩展 XSLT 样式表
- XSLT 扩展对象
- XSLT 参数
- 使用 msxsl:script 的脚本块
- 可恢复的 XSLT 错误
- 如何:转换节点片断
- 从 XslTransform 类迁移
- 如何:迁移 XslTransform 代码
- XSLT 安全注意事项
- XSLT 编译器 (xsltc.exe)
- 如何:通过使用程序集执行 XSLT 转换
- XslTransform 类的 XSLT 转换
- XslTransform 类中任意行为的实现
- XslTransform 类实现 XSLT 处理器
- XslTransform 的输出
- 不同存储区的 XSLT 转换
- 解析外部 XSLT 样式表和文档
- 样式表参数和扩展对象的 XsltArgumentList
- XSLT 样式表脚本使用<msxsl: script>
- 对 msxsl:node-set() 函数的支持
- 转换中的节点集
- 转换中的结果树片断
- 转换中的 XPathNavigator
- 转换中的 XPathNodeIterator
- XslTransform 的 XPathDocument 输入
- XslTransform 的 XmlDataDocument 输入
- XslTransform 的 XmlDocument 输入
- 使用 XML 架构
- XML 架构对象模型 (SOM)
- XML 架构对象模型概述
- 读写 XML 架构
- 生成 XML 架构
- 遍历 XML 架构
- 编辑 XML 架构
- 包含或导入 XML 架构
- 用于编译架构的 XmlSchemaSet
- 后架构编译信息集
- 使用 XmlSchemaSet 进行 XML 架构 (XSD) 验证
- XmlSchemaCollection 架构编译
- 使用 XmlSchemaCollection 进行 XDR 验证
- 使用 XmlSchemaCollection 进行 XML 架构 (XSD) 验证
- XmlSchemaValidator 基于推送的验证
- 推断 XML 架构
- 从 XML 文档推断架构
- 推断架构节点类型和结构的规则
- 推断简单类型的规则
- 关系数据和 ADO.NET 的 XML 集成
- 管理 XML 文档中的命名空间
- System.Xml 类中的类型支持
- 将 XML 数据类型映射到 CLR 类型
- XML 类型支持实现说明
- XML 数据类型的转换
- 将字符串转换为 .NET Framework 数据类型
- 将 .NET Framework 类型转换为字符串
- 托管线程处理
- 托管线程处理基本知识
- 线程与线程处理
- 托管线程中的异常
- 为多线程处理同步数据
- 托管线程状态
- 前台和后台线程
- Windows 中的托管和非托管线程处理
- Thread.Suspend、垃圾回收和安全点
- 线程本地存储区:线程相关的静态字段和数据槽
- 托管线程中的取消
- 如何:通过轮询侦听取消请求
- 如何:注册取消请求的回调
- 如何:侦听具有等待句柄的取消请求
- 如何:侦听多个取消请求
- 使用线程和线程处理
- 启动时创建线程并传递数据
- 暂停和继续线程
- 销毁线程
- 调度线程
- 以协作方式取消线程
- 托管线程处理的最佳做法
- 线程处理对象和功能
- 托管线程池
- 计时器
- EventWaitHandle、AutoResetEvent、CountdownEvent、ManualResetEvent
- EventWaitHandle
- AutoResetEvent
- ManualResetEvent 和 ManualResetEventSlim
- CountdownEvent
- Mutexes
- 互锁操作
- 读取器/编写器锁
- Semaphore 和 SemaphoreSlim
- 同步基元概述
- 屏障 (.NET Framework)
- 如何:使用屏障来使并发操作保持同步
- SpinLock
- 如何:使用 SpinLock 进行低级别同步
- 如何:在 SpinLock 中启用线程跟踪模式
- SpinWait
- 如何:使用 SpinWait 实现两阶段等待操作
- .NET 中的并行编程
- 任务并行库 (TPL)
- 数据并行(任务并行库)
- 如何:编写简单的 Parallel.For 循环
- 如何:编写简单的 Parallel.ForEach 循环
- 如何:编写具有线程局部变量的 Parallel.For 循环
- 如何:编写具有线程局部变量的 Parallel.ForEach 循环
- 如何:取消 Parallel.For 或 ForEach Loop
- 如何:处理并行循环中的异常
- 如何:加快小型循环体的速度
- 如何:使用并行类循环访问文件目录
- 基于任务的异步编程
- 使用延续任务来链接任务
- 已附加和已分离的子任务
- 任务取消
- 异常处理(任务并行库)
- 如何:使用 Parallel.Invoke 来执行并行操作
- 如何:从任务中返回值
- 如何:取消任务及其子级
- 如何:创建预先计算的任务
- 如何:使用并行任务遍历二叉树
- 如何:解除嵌套任务的包装
- 如何:防止子任务附加到其父任务
- 数据流(任务并行库)
- 如何:将消息写入数据流块和从数据流块读取消息
- 如何:实现制造者-使用者数据流模式
- 如何:在数据流块收到数据时执行操作
- 演练:创建数据流管道
- 如何:取消链接数据流块
- 演练:在 Windows 窗体应用程序中使用数据流
- 如何:取消数据流块
- 演练:创建自定义数据流块类型
- 如何:使用 JoinBlock 从多个源读取数据
- 如何:指定数据流块中的并行度
- 如何:在数据流块中指定任务计划程序
- 演练:使用 BatchBlock 和 BatchedJoinBlock 提高效率
- 将 TPL 用于其他异步模式
- TPL 和传统 .NET Framework 异步编程
- 如何:在任务中包装 EAP 模式
- 数据并行和任务并行中的潜在缺陷
- 并行 LINQ (PLINQ)
- PLINQ 介绍
- 了解 PLINQ 中的加速
- PLINQ 中的顺序保留
- PLINQ 中的合并选项
- PLINQ 的潜在缺陷
- 如何:创建并执行简单的 PLINQ 查询
- 如何:在 PLINQ 查询中控制排序
- 如何:合并并行和顺序 LINQ 查询
- 如何:处理 PLINQ 查询中的异常
- 如何:取消 PLINQ 查询
- 如何:编写自定义 PLINQ 聚合函数
- 如何:在 PLINQ 中指定执行模式
- 如何:在 PLINQ 中指定合并选项
- 如何:使用 PLINQ 循环访问文件目录
- 如何:衡量 PLINQ 查询性能
- PLINQ 数据示例
- 用于并行编程的数据结构
- 并行诊断工具
- PLINQ 和 TPL 的自定义分区程序
- 如何:实现动态分区
- 如何:实现静态分区的分区程序
- PLINQ 和 TPL 中的 Lambda 表达式
- 其他阅读材料(并行编程)
- .NET Framework 中的安全性
- 安全性的基础概念
- 基于角色的安全性
- 主体和标识对象
- 如何:创建 WindowsPrincipal 对象
- 如何:创建 GenericPrincipal 和 GenericIdentity 对象
- 替换 Principal 对象
- 模拟与恢复
- .NET Framework 加密模型
- 加密服务
- 生成加密和解密的密钥
- 如何:将非对称密钥存储在密钥容器中
- 加密数据
- 解密数据
- 加密签名
- 使用哈希代码确保数据完整性
- 创建加密方案
- 如何:用对称密钥对 XML 元素进行加密
- 如何:用对称密钥对 XML 元素进行解密
- 如何:用非对称密钥对 XML 元素进行加密
- 如何:用非对称密钥对 XML 元素进行解密
- 如何:用 X.509 证书对 XML 元素进行加密
- 如何:用 X.509 证书对 XML 元素进行解密
- 如何:使用数字签名为 XML 文档签名
- 如何:验证 XML 文档的数字签名
- 如何:使用数据保护
- 如何:访问硬件加密设备
- 演练:创建加密应用程序
- 代码安全维护指南
- 保护状态数据
- 安全性和用户输入
- 安全和争用条件
- 安全性和进行中的代码生成
- .NET 中的序列化
- 序列化帮助主题
- 二进制序列化
- 序列化概念
- 基本序列化
- 有选择的序列化
- 自定义序列化
- 序列化过程中的步骤
- 版本容错序列化
- 序列化准则
- 如何:对序列化数据进行分块
- 如何: 确定是否可序列化的标准.NET 对象
- 请参阅
- 请参阅
- XML 和 SOAP 序列化
- 如何:控制派生类的序列化
- XML 序列化简介
- 如何:反序列化对象
- XML 序列化示例
- XML 架构定义工具和 XML 序列化
- How to: Use the XML Schema Definition Tool to Generate Classes and XML Schema Documents
- 使用属性控制 XML 序列化
- 用来控制 XML 序列化的属性
- 如何:指定 XML 流的替代元素名称
- 如何:序列化对象
- 如何:限定 XML 元素和 XML 属性名
- 使用 XML Web services 进行 XML 序列化
- 如何:将对象序列化为 SOAP 编码的 XML 流
- 如何:重写编码的 SOAP XML 序列化
- 用来控制编码的 SOAP 序列化的属性
- <system.xml.serialization> 元素
- <dateTimeSerialization> 元素
- <schemaImporterExtensions> 元素
- <xmlSerializer> 元素
- 序列化工具
- XML 序列化程序生成器工具 (Sgen.exe)
- XML Schema Definition Tool (Xsd.exe)
- .NET Framework 的序列化示例
- 基本序列化技术示例
- 使用 XmlSerializer 自定义序列化顺序
- SchemaImporterExtension 技术示例
- 版本容错序列化技术示例
- Web 服务泛型序列化技术示例
- Web 服务 IXmlSerializable 技术示例
- 使用 .NET Framework 针对多个平台开发
- 使用可移植类库的跨平台开发
- 将可移植类库与模型-视图-视图模型配合使用
- 面向多个平台的库的应用程序资源
- .NET Framework 对 Windows 应用商店应用程序和 Windows 运行时的支持情况
- 向 Windows 运行时传递 URI
- WindowsRuntimeStreamExtensions.AsRandomAccessStream(System.IO.Stream) 方法
.NET 中的格式化类型
格式设置是指将类、结构或枚举值的实例转换为其字符串表示形式的过程,通常使得最终的字符串可以显示给用户,或者进行反序列化以还原为原始数据类型。 此转换可能面临一系列挑战:
- 在内部存储值的方式不一定反映用户想要查看它们的方式。 例如,电话号码可以存储为 8009999999 格式,但此格式并非是用户友好的格式。 该电话号码应显示为 800-999-9999。 有关以这种方式设置数字格式的示例,请参见 自定义格式字符串 一节。
- 有时对象到其字符串表示形式的转换不是直观的。 例如,不清楚 Temperature 对象或 Person 对象的字符串表示形式应如何显示。 有关以各种方式设置 Temperature 对象格式的示例,请参见 标准格式字符串 一节。
- 值通常需要区分区域性的格式。 例如,在使用数字表示货币值的应用程序中,数字字符串应包括当前区域性的货币符号、组分隔符(在大多数区域性中,组分隔符为千位分隔符)和小数点符号。 有关示例,请参见 使用格式提供程序和 IFormatProvider 接口进行区分区域性的格式设置 一节。
- 应用程序可能需要以不同方式显示相同的值。 例如,应用程序可能通过显示名称的字符串表示形式来表示一个枚举成员,或通过显示基础值来表示该枚举成员。 有关以不同方式设置 DayOfWeek 枚举成员格式的示例,请参见 标准格式字符串 一节。
备注
格式设置将类型的值转换为字符串表示形式。 分析是格式设置的反向操作。 分析操作根据数据类型的字符串表示形式创建该数据类型的实例。 有关将字符串转换成其他数据类型的信息,请参见 Parsing Strings 。
.NET 提供了丰富的格式设置支持,使得开发人员可以满足这些要求。
本概述包含以下几节:
- .NET 中的格式设置
- 使用 ToString 方法的默认格式设置
- 重写 ToString 方法
- ToString 方法和格式字符串
- 使用格式提供程序和 IFormatProvider 接口进行区分区域性的格式设置
- IFormattable 接口
- 复合格式设置
- 使用 ICustomFormatter 进行自定义格式设置
- 相关主题
- 参考
.NET 中的格式设置
格式设置的基本机制是的默认实现 Object.ToString 方法,后者已在 默认格式设置使用 ToString 方法 本主题中后面的部分。 不过,.NET 提供了几种方法来修改和扩展其默认格式设置支持。 其中包括:
- 重写 Object.ToString 方法以定义对象值的自定义字符串表示形式。 有关更多信息,请参见本主题后面的 重写 ToString 方法 部分。
- 定义格式说明符,格式说明符允许对象值的字符串表示形式采用多种形式。 例如,以下语句中的
X
格式说明符将整数转换为十六进制值的字符串表示形式。int integerValue = 60312; Console.WriteLine(integerValue.ToString("X")); // Displays EB98.
Dim integerValue As Integer = 60312 Console.WriteLine(integerValue.ToString("X")) ' Displays EB98.
有关格式说明符的更多信息,请参见 ToString 方法和格式字符串 部分。
- 使用格式提供程序以利用特定区域性的格式设置约定。 例如,以下语句通过使用 en-US 区域性的格式设置约定来显示货币值。
double cost = 1632.54; Console.WriteLine(cost.ToString("C", new System.Globalization.CultureInfo("en-US"))); // The example displays the following output: // $1,632.54
Dim cost As Double = 1632.54 Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US"))) ' The example displays the following output: ' $1,632.54
有关使用格式提供程序进行格式设置的更多信息,请参见 格式提供程序和 IFormatProvider 接口 部分。
- 实现 IFormattable 接口可以支持使用 Convert 类的字符串转换以及复合格式设置。 有关更多信息,请参见 IFormattable 接口 部分。
- 使用复合格式设置来嵌入较大字符串中值的字符串表示形式。 有关更多信息,请参见 复合格式设置 部分。
- 实现 ICustomFormatter 和 IFormatProvider 可以提供完全自定义的格式设置解决方案。 有关更多信息,请参见 使用 ICustomFormatter 进行自定义格式设置 部分。
以下各部分分别使用这些方法来将对象转换为其字符串表示形式。
使用 ToString 方法的默认格式设置
每个从 System.Object 派生的类型都自动继承无参数的 ToString
方法,该方法在默认情况下返回类型的名称。 下面的示例演示默认 ToString
方法。 它定义一个名为 Automobile
、不具有实现的类。 当对该类进行实例化并调用其 ToString
方法时,它显示其类型名称。 请注意,此示例中未显式调用 ToString
方法。 Console.WriteLine(Object) 方法隐式调用作为参数传递给它的对象的 ToString
方法。
using System;
public class Automobile
{
// No implementation. All members are inherited from Object.
}
public class Example
{
public static void Main()
{
Automobile firstAuto = new Automobile();
Console.WriteLine(firstAuto);
}
}
// The example displays the following output:
// Automobile
Public Class Automobile
' No implementation. All members are inherited from Object.
End Class
Module Example
Public Sub Main()
Dim firstAuto As New Automobile()
Console.WriteLine(firstAuto)
End Sub
End Module
' The example displays the following output:
' Automobile
警告
从 Windows 8.1 开始, Windows 运行时 包括了具有单个方法 ( IStringable.ToString ) 的 IStringable 接口,用于提供默认格式支持。 但是,我们建议托管类型不实现 IStringable
接口。 有关更多信息,请参见 Windows 运行时 参考页上的
部分。IStringable
和 Object.ToString 接口
由于除接口以外的所有类型都派生自 Object ,因此会向自定义类或结构自动提供此功能。 但是,由默认 ToString
方法提供的功能具有以下限制:尽管它标识类型,但无法提供有关该类型的实例的任何信息。 若要提供可提供该对象相关信息的对象的字符串表示形式,必须重写 ToString
方法。
备注
结构继承自 ValueType ,而后者又派生自 Object 。 虽然 ValueType 会重写 Object.ToString ,但是其实现是相同的。
重写 ToString 方法
显示类型的名称这一用法往往有限,它不允许类型使用者区分实例。 但是,你可以重写 ToString
方法,以提供更有用的对象值表示形式。 下面的示例定义 Temperature
对象并重写其 ToString
方法,以便以摄氏度显示温度。
using System;
public class Temperature
{
private decimal temp;
public Temperature(decimal temperature)
{
this.temp = temperature;
}
public override string ToString()
{
return this.temp.ToString("N1") + "°C";
}
}
public class Example
{
public static void Main()
{
Temperature currentTemperature = new Temperature(23.6m);
Console.WriteLine("The current temperature is " +
currentTemperature.ToString());
}
}
// The example displays the following output:
// The current temperature is 23.6°C.
Public Class Temperature
Private temp As Decimal
Public Sub New(temperature As Decimal)
Me.temp = temperature
End Sub
Public Overrides Function ToString() As String
Return Me.temp.ToString("N1") + "°C"
End Function
End Class
Module Example
Public Sub Main()
Dim currentTemperature As New Temperature(23.6d)
Console.WriteLine("The current temperature is " +
currentTemperature.ToString())
End Sub
End Module
' The example displays the following output:
' The current temperature is 23.6°C.
在.NET 中, ToString
每个基元值类型的方法已被重写,来显示对象的值而非其名称。 下表显示每种基元类型的重写。 请注意,大多数重写方法调用 ToString
方法的另一个重载并向其传递用于定义其类型的一般格式的 G
格式说明符和表示当前区域性的 IFormatProvider 对象。
类型 | ToString 重写 |
---|---|
Boolean | 返回 Boolean.TrueString 或 Boolean.FalseString 。 |
Byte | 调用 Byte.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Byte 值的格式。 |
Char | 以字符串形式返回字符。 |
DateTime | 调用 DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) 可以为当前区域性设置日期和时间值的格式。 |
Decimal | 调用 Decimal.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Decimal 值的格式。 |
Double | 调用 Double.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Double 值的格式。 |
Int16 | 调用 Int16.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Int16 值的格式。 |
Int32 | 调用 Int32.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Int32 值的格式。 |
Int64 | 调用 Int64.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Int64 值的格式。 |
SByte | 调用 SByte.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 SByte 值的格式。 |
Single | 调用 Single.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 Single 值的格式。 |
UInt16 | 调用 UInt16.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 UInt16 值的格式。 |
UInt32 | 调用 UInt32.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 UInt32 值的格式。 |
UInt64 | 调用 UInt64.ToString("G", NumberFormatInfo.CurrentInfo) 可以为当前区域性设置 UInt64 值的格式。 |
ToString 方法和格式字符串
对象具有单一字符串表示形式时,可以依赖于默认 ToString
方法或重写 ToString
。 但是,对象的值通常具有多种表示形式。 例如,温度可以用华氏度、摄氏度或开氏度来表示。 同样,整数值 10 可以表示为多种形式,包括 10、10.0、1.0e01 或 $10.00。
为了允许单个值具有多种字符串表示形式,.NET 使用格式字符串。 格式字符串是包含一个或多个预定义格式说明符的字符串,这些格式说明符是单一字符或字符组,用于定义 ToString
方法应如何设置其输出格式。 然后将格式字符串作为参数传递给对象的 ToString
方法,并确定应如何显示该对象值的字符串表示形式。
.NET 中的所有数字类型、日期和时间类型以及枚举类型都支持一组预定义的格式说明符。 还可以使用格式字符串定义你应用程序所定义的数据类型的多种字符串表示形式。
标准格式字符串
标准格式字符串包含单个格式说明符,该格式说明符是一个字母字符,用于定义应用该格式说明符的对象的字符串表示形式,此外,它还包含一个可选的精度说明符,该精度说明符影响在结果字符串中显示的位数。 如果省略或不支持精度说明符,则标准格式说明符等效于标准格式字符串。
.NET 为所有数字类型、所有日期和时间类型以及所有枚举类型定义一组标准格式说明符。 例如,这些类别中的每一类别都支持 G
标准格式说明符,该标准格式说明符定义该类型的值的一般字符串表示形式。
枚举类型的标准格式字符串直接控制值的字符串表示形式。 传递给枚举值的 ToString
方法的格式字符串决定是使用其字符串名称( G
和 F
格式说明符)、基础整数值( D
格式说明符)还是十六进制值( X
格式说明符)来显示值。 下面的示例演示如何使用标准格式字符串来设置 DayOfWeek 枚举值的格式。
DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};
foreach (string formatString in formatStrings)
Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
// Monday
// Monday
// 1
// 00000001
Dim thisDay As DayOfWeek = DayOfWeek.Monday
Dim formatStrings() As String = {"G", "F", "D", "X"}
For Each formatString As String In formatStrings
Console.WriteLine(thisDay.ToString(formatString))
Next
' The example displays the following output:
' Monday
' Monday
' 1
' 00000001
有关枚举格式字符串的信息,请参见 Enumeration Format Strings 。
数字类型的标准格式字符串通常定义一个结果字符串,该结果字符串的确切显示由一个或多个属性值控制。 例如, C
格式说明符会将数字的格式设置为货币值。 调用 ToString
方法并使用 C
格式说明符作为唯一参数时,来自当前区域性的 NumberFormatInfo 对象的以下属性值用于定义数字值的字符串表示形式:
- CurrencySymbol 属性,指定当前区域性的货币符号。
- CurrencyNegativePattern 或 CurrencyPositivePattern 属性,其返回的整数决定:
- 货币符号的位置。
- 负值由前导负号、尾随负号还是括号来表示。
- 在数字值和货币符号之间是否有空格。
- CurrencyDecimalDigits 属性,定义结果字符串中的小数位数。
- CurrencyDecimalSeparator 属性,定义结果字符串中的小数分隔符符号。
- CurrencyGroupSeparator 属性,定义组分隔符符号。
- CurrencyGroupSizes 属性,定义小数点左边每个组的数字位数。
- NegativeSign 属性,确定在未使用括号表示负值时结果字符串中使用的负号。
此外,数字格式字符串可以包含一个精度说明符。 该说明符的含义取决于与其一起使用的格式字符串,但是,它通常指示应在结果字符串中显示的总位数或小数位数。 例如,下面的示例使用 X4
标准数字字符串和精度说明符来创建具有四个十六进制位的字符串值。
byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
// 000C
// 00A3
// 00FF
Dim byteValues() As Byte = { 12, 163, 255 }
For Each byteValue As Byte In byteValues
Console.WriteLine(byteValue.ToString("X4"))
Next
' The example displays the following output:
' 000C
' 00A3
' 00FF
有关标准数字格式字符串的更多信息,请参见 Standard Numeric Format Strings 。
日期和时间值的标准格式字符串是由特定 DateTimeFormatInfo 属性存储的自定义格式字符串的别名。 例如,如果使用 D
格式说明符调用日期和时间值的 ToString
方法,则使用当前区域性的 DateTimeFormatInfo.LongDatePattern 属性中存储的自定义格式字符串来显示日期和时间。 (有关自定义格式字符串的详细信息,请参阅 下一节 。) 下面的示例阐释了此关系。
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
DateTime date1 = new DateTime(2009, 6, 30);
Console.WriteLine("D Format Specifier: {0:D}", date1);
string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
Console.WriteLine("'{0}' custom format string: {1}",
longPattern, date1.ToString(longPattern));
}
}
// The example displays the following output when run on a system whose
// current culture is en-US:
// D Format Specifier: Tuesday, June 30, 2009
// 'dddd, MMMM dd, yyyy' custom format string: Tuesday, June 30, 2009
Imports System.Globalization
Module Example
Public Sub Main()
Dim date1 As Date = #6/30/2009#
Console.WriteLine("D Format Specifier: {0:D}", date1)
Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
Console.WriteLine("'{0}' custom format string: {1}", _
longPattern, date1.ToString(longPattern))
End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
' D Format Specifier: Tuesday, June 30, 2009
' 'dddd, MMMM dd, yyyy' custom format string: Tuesday, June 30, 2009
有关标准日期和时间格式字符串的更多信息,请参见 标准日期和时间格式字符串 。
还可以使用标准格式字符串来定义应用程序所定义的对象的字符串表示形式,它由对象的 ToString(String)
方法生成。 可以定义对象支持的特定标准格式说明符,还可以决定这些格式说明符是否区分大小写。 ToString(String)
方法的实现应支持下列各项:
- 一个
G
格式说明符,表示对象的常用或通用格式。 对象的ToString
方法的无参数重载应调用其ToString(String)
重载,并向其传递G
标准格式字符串。 - 支持等于空引用(在 Visual Basic 中为
Nothing
)的格式说明符。 应视等于空引用的格式说明符与G
格式说明符等效。
例如, Temperature
类可以用摄氏度在内部存储温度,并使用格式限定符以摄氏度、华氏度和开氏度表示 Temperature
对象的值。 下面的示例进行了这方面的演示。
using System;
public class Temperature
{
private decimal m_Temp;
public Temperature(decimal temperature)
{
this.m_Temp = temperature;
}
public decimal Celsius
{
get { return this.m_Temp; }
}
public decimal Kelvin
{
get { return this.m_Temp + 273.15m; }
}
public decimal Fahrenheit
{
get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
}
public override string ToString()
{
return this.ToString("C");
}
public string ToString(string format)
{
// Handle null or empty string.
if (String.IsNullOrEmpty(format)) format = "C";
// Remove spaces and convert to uppercase.
format = format.Trim().ToUpperInvariant();
// Convert temperature to Fahrenheit and return string.
switch (format)
{
// Convert temperature to Fahrenheit and return string.
case "F":
return this.Fahrenheit.ToString("N2") + " °F";
// Convert temperature to Kelvin and return string.
case "K":
return this.Kelvin.ToString("N2") + " K";
// return temperature in Celsius.
case "G":
case "C":
return this.Celsius.ToString("N2") + " °C";
default:
throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
}
}
}
public class Example
{
public static void Main()
{
Temperature temp1 = new Temperature(0m);
Console.WriteLine(temp1.ToString());
Console.WriteLine(temp1.ToString("G"));
Console.WriteLine(temp1.ToString("C"));
Console.WriteLine(temp1.ToString("F"));
Console.WriteLine(temp1.ToString("K"));
Temperature temp2 = new Temperature(-40m);
Console.WriteLine(temp2.ToString());
Console.WriteLine(temp2.ToString("G"));
Console.WriteLine(temp2.ToString("C"));
Console.WriteLine(temp2.ToString("F"));
Console.WriteLine(temp2.ToString("K"));
Temperature temp3 = new Temperature(16m);
Console.WriteLine(temp3.ToString());
Console.WriteLine(temp3.ToString("G"));
Console.WriteLine(temp3.ToString("C"));
Console.WriteLine(temp3.ToString("F"));
Console.WriteLine(temp3.ToString("K"));
Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
}
}
// The example displays the following output:
// 0.00 °C
// 0.00 °C
// 0.00 °C
// 32.00 °F
// 273.15 K
// -40.00 °C
// -40.00 °C
// -40.00 °C
// -40.00 °F
// 233.15 K
// 16.00 °C
// 16.00 °C
// 16.00 °C
// 60.80 °F
// 289.15 K
// The temperature is now 16.00 °C.
Public Class Temperature
Private m_Temp As Decimal
Public Sub New(temperature As Decimal)
Me.m_Temp = temperature
End Sub
Public ReadOnly Property Celsius() As Decimal
Get
Return Me.m_Temp
End Get
End Property
Public ReadOnly Property Kelvin() As Decimal
Get
Return Me.m_Temp + 273.15d
End Get
End Property
Public ReadOnly Property Fahrenheit() As Decimal
Get
Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
End Get
End Property
Public Overrides Function ToString() As String
Return Me.ToString("C")
End Function
Public Overloads Function ToString(format As String) As String
' Handle null or empty string.
If String.IsNullOrEmpty(format) Then format = "C"
' Remove spaces and convert to uppercase.
format = format.Trim().ToUpperInvariant()
Select Case format
Case "F"
' Convert temperature to Fahrenheit and return string.
Return Me.Fahrenheit.ToString("N2") & " °F"
Case "K"
' Convert temperature to Kelvin and return string.
Return Me.Kelvin.ToString("N2") & " K"
Case "C", "G"
' Return temperature in Celsius.
Return Me.Celsius.ToString("N2") & " °C"
Case Else
Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
End Select
End Function
End Class
Public Module Example
Public Sub Main()
Dim temp1 As New Temperature(0d)
Console.WriteLine(temp1.ToString())
Console.WriteLine(temp1.ToString("G"))
Console.WriteLine(temp1.ToString("C"))
Console.WriteLine(temp1.ToString("F"))
Console.WriteLine(temp1.ToString("K"))
Dim temp2 As New Temperature(-40d)
Console.WriteLine(temp2.ToString())
Console.WriteLine(temp2.ToString("G"))
Console.WriteLine(temp2.ToString("C"))
Console.WriteLine(temp2.ToString("F"))
Console.WriteLine(temp2.ToString("K"))
Dim temp3 As New Temperature(16d)
Console.WriteLine(temp3.ToString())
Console.WriteLine(temp3.ToString("G"))
Console.WriteLine(temp3.ToString("C"))
Console.WriteLine(temp3.ToString("F"))
Console.WriteLine(temp3.ToString("K"))
Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3))
End Sub
End Module
' The example displays the following output:
' 0.00 °C
' 0.00 °C
' 0.00 °C
' 32.00 °F
' 273.15 K
' -40.00 °C
' -40.00 °C
' -40.00 °C
' -40.00 °F
' 233.15 K
' 16.00 °C
' 16.00 °C
' 16.00 °C
' 60.80 °F
' 289.15 K
' The temperature is now 16.00 °C.
自定义格式字符串
除了标准格式字符串之外,.NET 还为数字值以及日期和时间值定义了自定义格式字符串。 自定义格式字符串由定义值的字符串表示形式的一个或多个自定义格式说明符组成。 例如,对于 en-US 区域性,自定义日期和时间格式字符串 yyyy/mm/dd hh:mm:ss.ffff t zzz
将日期转换为 2008/11/15 07:45:00.0000 P -08:00
形式的字符串表示形式。 同样,自定义格式字符串 0000
将整数值 12 转换为 0012
。 有关自定义格式字符串的完整列表,请参见 Custom Date and Time Format Strings 和 Custom Numeric Format Strings 。
如果格式字符串仅包含一个自定义格式说明符,则此格式说明符前面应带有百分比 (%) 符号,以免与标准格式说明符混淆。 下面的示例使用 M
自定义格式说明符来显示特定日期的一位数或两位数的月份。
DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M")); // Displays 9
Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M")) ' Displays 9
日期和时间值的许多标准格式字符串均是由 DateTimeFormatInfo 对象的属性所定义的自定义格式字符串的别名。 自定义格式字符串还为设置数字值或日期和时间值的应用程序定义格式提供了很大的灵活性。 你可以通过将多个自定义格式说明符组合成一个自定义格式字符串来为数字值以及日期和时间值定义你自己的自定义结果字符串。 下面的示例定义一个自定义格式字符串,该字符串在月份名称、日期和年份后的括号中显示星期几。
string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));
// The example displays the following output if run on a system
// whose language is English:
// August 28, 2009 (Friday)
Dim customFormat As String = "MMMM dd, yyyy (dddd)"
Dim date1 As Date = #8/28/2009#
Console.WriteLine(date1.ToString(customFormat))
' The example displays the following output if run on a system
' whose language is English:
' August 28, 2009 (Friday)
以下示例定义了自定义格式字符串,其中 Int64 值显示为标准的美国七位数电话号码及其区号。
using System;
public class Example
{
public static void Main()
{
long number = 8009999999;
string fmt = "000-000-0000";
Console.WriteLine(number.ToString(fmt));
}
}
// The example displays the following output:
// 800-999-9999
Module Example
Public Sub Main()
Dim number As Long = 8009999999
Dim fmt As String = "000-000-0000"
Console.WriteLine(number.ToString(fmt))
End Sub
End Module
' The example displays the following output:
' The example displays the following output:
' 800-999-9999
尽管标准格式字符串一般可以满足应用程序定义的类型的大多数格式设置需求,但你还可以定义自定义格式说明符来设置类型的格式。
格式字符串和.NET 类库类型
所有数值类型(即 Byte 、 Decimal 、 Double 、 Int16 、 Int32 、 Int64 、 SByte 、 Single 、 UInt16 、 UInt32 、 UInt64 和 BigInteger 类型)
以及 DateTime 、 DateTimeOffset 、 TimeSpan 、 Guid 和所有枚举类型支持使用格式字符串设置格式。 有关各类型支持的特定格式字符串的信息,请参阅下列主题
标题 | 定义 |
---|---|
Standard Numeric Format Strings | 描述用于创建数字值的常用字符串表示形式的标准格式字符串。 |
Custom Numeric Format Strings | 描述用于创建数字值的应用程序特定格式的自定义格式字符串。 |
Standard Date and Time Format Strings | 描述用于创建 DateTime 值的常用字符串表示形式的标准格式字符串。 |
Custom Date and Time Format Strings | 描述用于创建 DateTime 值的应用程序特定格式的自定义格式字符串。 |
标准 TimeSpan 格式字符串 | 描述用于创建时间间隔的常用字符串表示形式的标准格式字符串。 |
自定义 TimeSpan 格式字符串 | 描述用于创建时间间隔的应用程序特定格式的自定义格式字符串。 |
Enumeration Format Strings | 描述用于创建枚举值的字符串表示形式的标准格式字符串。 |
Guid.ToString(String) | 描述 Guid 值的标准格式字符串。 |
使用格式提供程序和 IFormatProvider 接口进行区分区域性的格式设置
尽管格式说明符允许你自定义对象的格式设置,但是生成有意义的对象字符串表示形式通常需要附加格式设置信息。 例如,通过使用 C
标准格式字符串或自定义格式字符串(如 $ #,#.00
)来将数字格式设置为货币值至少需要提供有关正确的货币符号、组分隔符和小数点分隔符的信息,以便包括在带有格式的字符串中。 在.NET 中,此附加格式设置信息将可通过 IFormatProvider 接口,作为一个或多个重载的参数提供 ToString
的数字类型以及日期和时间类型的方法。 IFormatProvider 实现在.NET 中使用,以支持特定于区域性的格式设置。 下面的示例演示在使用三个代表不同区域的 IFormatProvider 对象设置某个对象的格式时,该对象的字符串表示形式将如何变化。
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
decimal value = 1603.42m;
Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
}
}
// The example displays the following output:
// $1,603.420
// 1 603,420 €
// 1.603,420 €
Imports System.Globalization
Public Module Example
Public Sub Main()
Dim value As Decimal = 1603.42d
Console.WriteLine(value.ToString("C3", New CultureInfo("en-US")))
Console.WriteLine(value.ToString("C3", New CultureInfo("fr-FR")))
Console.WriteLine(value.ToString("C3", New CultureInfo("de-DE")))
End Sub
End Module
' The example displays the following output:
' $1,603.420
' 1 603,420 €
' 1.603,420 €
IFormatProvider 接口包含一个 GetFormat(Type) 方法,该方法只有一个参数,该参数指定提供格式设置信息的对象类型。 如果该方法可以提供该类型的对象,则返回它。 否则,它返回空引用(在 Visual Basic 中为 Nothing
)。
IFormatProvider.GetFormat 为回调方法。 调用包含 ToString
参数的 IFormatProvider 方法重载时,它调用该 GetFormat 对象的 IFormatProvider 方法。 GetFormat 方法负责将提供所需格式设置信息(就像 formatType
参数指定的一样)的对象返回给 ToString
方法。
一些格式设置或字符串转换方法包含 IFormatProvider 类型的参数,但是很多情况下在调用该方法时将忽略该参数的值。 下表列出了使用 Type 对象的参数和类型的一些格式设置方法,该对象传递给 IFormatProvider.GetFormat 方法。
方法 | formatType 参数的类型 |
---|---|
数字类型的 ToString 方法 | System.Globalization.NumberFormatInfo |
日期和时间类型的 ToString 方法 | System.Globalization.DateTimeFormatInfo |
String.Format | System.ICustomFormatter |
StringBuilder.AppendFormat | System.ICustomFormatter |
备注
将重载数字类型以及日期和时间类型的 ToString
方法,并且只有某些重载包含 IFormatProvider 参数。 如果方法没有 IFormatProvider 类型的参数,则改为传递 CultureInfo.CurrentCulture 属性所返回的对象。 例如,对默认 Int32.ToString() 方法的调用最终将导致诸如以下的方法调用: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)
。
.NET 提供三种类实现 IFormatProvider :
- DateTimeFormatInfo 类,提供特定区域性的日期和时间值的格式设置信息。 其 IFormatProvider.GetFormat 实现返回它自身的实例。
- NumberFormatInfo 类,提供特定区域性的数字格式设置信息。 其 IFormatProvider.GetFormat 实现返回它自身的实例。
- CultureInfo 。 其 IFormatProvider.GetFormat 实现可以返回一个 NumberFormatInfo 对象(可提供数字格式设置信息)或一个 DateTimeFormatInfo 对象(可提供日期和时间值的格式设置信息)。
你还可以实现自己的格式提供程序来替换上述任意一个类。 但是,如果你的实现的 GetFormat 方法必须向 ToString
方法提供格式设置信息,则它必须返回上表中列出的相应类型的对象。
数值的区分区域性的格式设置
默认情况下,数值的格式设置是区分区域性的。 如果在调用格式设置方法时不指定区域性,则将使用当前线程区域性的格式设置约定。 下面的示例演示了这一点,其中对当前线程区域性进行了四次更改,随后调用了 Decimal.ToString(String) 方法。 每次更改后,结果字符串均反映当前区域性的格式设置约定。 这是因为 ToString
和 ToString(String)
方法会包装对每个数值类型的 ToString(String, IFormatProvider)
方法的调用。
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
Decimal value = 1043.17m;
foreach (var cultureName in cultureNames) {
// Change the current thread culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
Console.WriteLine("The current culture is {0}",
Thread.CurrentThread.CurrentCulture.Name);
Console.WriteLine(value.ToString("C2"));
Console.WriteLine();
}
}
}
// The example displays the following output:
// The current culture is en-US
// $1,043.17
//
// The current culture is fr-FR
// 1 043,17 €
//
// The current culture is es-MX
// $1,043.17
//
// The current culture is de-DE
// 1.043,17 €
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim cultureNames() As String = { "en-US", "fr-FR", "es-MX", "de-DE" }
Dim value As Decimal = 1043.17d
For Each cultureName In cultureNames
' Change the current thread culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
Console.WriteLine("The current culture is {0}",
Thread.CurrentThread.CurrentCulture.Name)
Console.WriteLine(value.ToString("C2"))
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' The current culture is en-US
' $1,043.17
'
' The current culture is fr-FR
' 1 043,17 €
'
' The current culture is es-MX
' $1,043.17
'
' The current culture is de-DE
' 1.043,17 €
你还可以设置特定区域性数值的格式,方法是调用具有 ToString
参数的 provider
重载,并将其作为以下对象之一的参数进行传递:
- 一个 CultureInfo 对象,此对象代表要使用其格式设置约定的区域性。 它的 CultureInfo.GetFormat 方法会返回 CultureInfo.NumberFormat 属性的值,即提供数字区域性特定格式设置信息的 NumberFormatInfo 对象。
- 一个 NumberFormatInfo 对象,此对象用于定义要使用的区域性特定格式设置约定。 它的 GetFormat 方法会返回它自身的一个实例。
下面的示例使用了表示英语(美国)和英语(英国)区域性以及法语和俄罗斯语非特定区域性的 NumberFormatInfo 对象,来设置浮点数字的格式。
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
Double value = 1043.62957;
string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };
foreach (var name in cultureNames) {
NumberFormatInfo nfi = CultureInfo.CreateSpecificCulture(name).NumberFormat;
Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi));
}
}
}
// The example displays the following output:
// en-US: 1,043.630
// en-GB: 1,043.630
// ru: 1 043,630
// fr: 1 043,630
Imports System.Globalization
Module Example
Public Sub Main()
Dim value As Double = 1043.62957
Dim cultureNames() As String = { "en-US", "en-GB", "ru", "fr" }
For Each name In cultureNames
Dim nfi As NumberFormatInfo = CultureInfo.CreateSpecificCulture(name).NumberFormat
Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi))
Next
End Sub
End Module
' The example displays the following output:
' en-US: 1,043.630
' en-GB: 1,043.630
' ru: 1 043,630
' fr: 1 043,630
日期和时间值的区分区域性的格式设置
默认情况下,日期和时间值的格式设置是区分区域性的。 如果在调用格式设置方法时不指定区域性,则将使用当前线程区域性的格式设置约定。 下面的示例演示了这一点,其中对当前线程区域性进行了四次更改,随后调用了 DateTime.ToString(String) 方法。 每次更改后,结果字符串均反映当前区域性的格式设置约定。 这是因为 DateTime.ToString() 、 DateTime.ToString(String) 、 DateTimeOffset.ToString() 和 DateTimeOffset.ToString(String) 方法会包装对 DateTime.ToString(String, IFormatProvider) 及 DateTimeOffset.ToString(String, IFormatProvider) 方法的调用。
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
DateTime dateToFormat = new DateTime(2012, 5, 28, 11, 30, 0);
foreach (var cultureName in cultureNames) {
// Change the current thread culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
Console.WriteLine("The current culture is {0}",
Thread.CurrentThread.CurrentCulture.Name);
Console.WriteLine(dateToFormat.ToString("F"));
Console.WriteLine();
}
}
}
// The example displays the following output:
// The current culture is en-US
// Monday, May 28, 2012 11:30:00 AM
//
// The current culture is fr-FR
// lundi 28 mai 2012 11:30:00
//
// The current culture is es-MX
// lunes, 28 de mayo de 2012 11:30:00 a.m.
//
// The current culture is de-DE
// Montag, 28. Mai 2012 11:30:00
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim cultureNames() As String = { "en-US", "fr-FR", "es-MX", "de-DE" }
Dim dateToFormat As Date = #5/28/2012 11:30AM#
For Each cultureName In cultureNames
' Change the current thread culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
Console.WriteLine("The current culture is {0}",
Thread.CurrentThread.CurrentCulture.Name)
Console.WriteLine(dateToFormat.ToString("F"))
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' The current culture is en-US
' Monday, May 28, 2012 11:30:00 AM
'
' The current culture is fr-FR
' lundi 28 mai 2012 11:30:00
'
' The current culture is es-MX
' lunes, 28 de mayo de 2012 11:30:00 a.m.
'
' The current culture is de-DE
' Montag, 28. Mai 2012 11:30:00
你还可以设置特定区域性日期和时间值的格式,方法是调用具有 DateTime.ToString 参数的 DateTimeOffset.ToString 或 provider
重载,并将其作为以下对象之一的参数进行传递:
- 一个 CultureInfo 对象,此对象代表要使用其格式设置约定的区域性。 它的 CultureInfo.GetFormat 方法会返回 CultureInfo.DateTimeFormat 属性的值,即提供日期和时间值区域性特定格式设置信息的 DateTimeFormatInfo 对象。
- 一个 DateTimeFormatInfo 对象,此对象用于定义要使用的区域性特定格式设置约定。 它的 GetFormat 方法会返回它自身的一个实例。
下面的示例使用了表示英语(美国)和英语(英国)区域性以及法语和俄罗斯语非特定区域性的 DateTimeFormatInfo 对象,来设置日期的格式。
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
DateTime dat1 = new DateTime(2012, 5, 28, 11, 30, 0);
string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };
foreach (var name in cultureNames) {
DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture(name).DateTimeFormat;
Console.WriteLine("{0}: {1}", name, dat1.ToString(dtfi));
}
}
}
// The example displays the following output:
// en-US: 5/28/2012 11:30:00 AM
// en-GB: 28/05/2012 11:30:00
// ru: 28.05.2012 11:30:00
// fr: 28/05/2012 11:30:00
Imports System.Globalization
Module Example
Public Sub Main()
Dim dat1 As Date = #5/28/2012 11:30AM#
Dim cultureNames() As String = { "en-US", "en-GB", "ru", "fr" }
For Each name In cultureNames
Dim dtfi As DateTimeFormatInfo = CultureInfo.CreateSpecificCulture(name).DateTimeFormat
Console.WriteLine("{0}: {1}", name, dat1.ToString(dtfi))
Next
End Sub
End Module
' The example displays the following output:
' en-US: 5/28/2012 11:30:00 AM
' en-GB: 28/05/2012 11:30:00
' ru: 28.05.2012 11:30:00
' fr: 28/05/2012 11:30:00
IFormattable 接口
通常,使用格式字符串和一个 ToString
参数来重载 IFormatProvider 方法的类型还实现 IFormattable 接口。 此接口具有一个成员 IFormattable.ToString(String, IFormatProvider) ,该成员同时将格式字符串和格式提供程序作为参数。
对应用程序定义的类实现 IFormattable 接口具有两大优势:
- 支持使用 Convert 类进行字符串转换。 对 Convert.ToString(Object) 和 Convert.ToString(Object, IFormatProvider) 方法的调用会自动调用 IFormattable 实现。
- 支持复合格式设置。 如果使用包含格式字符串的格式项设置自定义类型的格式,则公共语言运行时自动调用 IFormattable 实现,并向其传递该格式字符串。 有关采用 String.Format 或 Console.WriteLine 等方法进行复合格式设置的更多信息,请参见 复合格式设置 部分。
下面的示例定义一个实现 Temperature
接口的 IFormattable 类。 它支持 C
或 G
格式说明符(用于以摄氏度显示温度)、 F
格式说明符(用于以华氏度显示温度)和 K
格式说明符(用于以开氏度显示温度)。
using System;
using System.Globalization;
public class Temperature : IFormattable
{
private decimal m_Temp;
public Temperature(decimal temperature)
{
this.m_Temp = temperature;
}
public decimal Celsius
{
get { return this.m_Temp; }
}
public decimal Kelvin
{
get { return this.m_Temp + 273.15m; }
}
public decimal Fahrenheit
{
get { return Math.Round((decimal) this.m_Temp * 9 / 5 + 32, 2); }
}
public override string ToString()
{
return this.ToString("G", null);
}
public string ToString(string format)
{
return this.ToString(format, null);
}
public string ToString(string format, IFormatProvider provider)
{
// Handle null or empty arguments.
if (String.IsNullOrEmpty(format))
format = "G";
// Remove any white space and covert to uppercase.
format = format.Trim().ToUpperInvariant();
if (provider == null)
provider = NumberFormatInfo.CurrentInfo;
switch (format)
{
// Convert temperature to Fahrenheit and return string.
case "F":
return this.Fahrenheit.ToString("N2", provider) + "°F";
// Convert temperature to Kelvin and return string.
case "K":
return this.Kelvin.ToString("N2", provider) + "K";
// Return temperature in Celsius.
case "C":
case "G":
return this.Celsius.ToString("N2", provider) + "°C";
default:
throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
}
}
}
Imports System.Globalization
Public Class Temperature : Implements IFormattable
Private m_Temp As Decimal
Public Sub New(temperature As Decimal)
Me.m_Temp = temperature
End Sub
Public ReadOnly Property Celsius() As Decimal
Get
Return Me.m_Temp
End Get
End Property
Public ReadOnly Property Kelvin() As Decimal
Get
Return Me.m_Temp + 273.15d
End Get
End Property
Public ReadOnly Property Fahrenheit() As Decimal
Get
Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
End Get
End Property
Public Overrides Function ToString() As String
Return Me.ToString("G", Nothing)
End Function
Public Overloads Function ToString(format As String) As String
Return Me.ToString(format, Nothing)
End Function
Public Overloads Function ToString(format As String, provider As IFormatProvider) As String _
Implements IFormattable.ToString
' Handle null or empty arguments.
If String.IsNullOrEmpty(format) Then format = "G"
' Remove any white space and convert to uppercase.
format = format.Trim().ToUpperInvariant()
If provider Is Nothing Then provider = NumberFormatInfo.CurrentInfo
Select Case format
' Convert temperature to Fahrenheit and return string.
Case "F"
Return Me.Fahrenheit.ToString("N2", provider) & "°F"
' Convert temperature to Kelvin and return string.
Case "K"
Return Me.Kelvin.ToString("N2", provider) & "K"
' Return temperature in Celsius.
Case "C", "G"
Return Me.Celsius.ToString("N2", provider) & "°C"
Case Else
Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
End Select
End Function
End Class
下面的示例实例化一个 Temperature
对象。 然后,它调用 ToString 方法,并使用多个复合格式字符串获取 Temperature
对象的不同字符串表示形式。 其中每一个方法调用都依次调用 IFormattable 类的 Temperature
实现。
public class Example
{
public static void Main()
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
Temperature temp = new Temperature(22m);
Console.WriteLine(Convert.ToString(temp, new CultureInfo("ja-JP")));
Console.WriteLine("Temperature: {0:K}", temp);
Console.WriteLine("Temperature: {0:F}", temp);
Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp));
}
}
// The example displays the following output:
// 22.00°C
// Temperature: 295.15K
// Temperature: 71.60°F
// Temperature: 71,60°F
Public Module Example
Public Sub Main()
Dim temp As New Temperature(22d)
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US")
Console.WriteLine(Convert.ToString(temp1, New CultureInfo("ja-JP")))
Console.WriteLine("Temperature: {0:K}", temp)
Console.WriteLine("Temperature: {0:F}", temp)
Console.WriteLine(String.Format(New CultureInfo("fr-FR"), "Temperature: {0:F}", temp))
End Sub
End Module
' The example displays the following output:
' 22.00°C
' Temperature: 295.15K
' Temperature: 71.60°F
' Temperature: 71,60°F
复合格式设置
一些方法(如 String.Format 和 StringBuilder.AppendFormat )支持复合格式设置。 复合格式字符串是一种模板,该模板返回合并了零个、一个或多个对象的字符串表示形式的单一字符串。 每个对象均由复合格式字符串中的索引格式项表示。 格式项的索引对应于格式项在方法的参数列表中所表示的对象位置。 索引是从零开始的。 例如,在以下对 String.Format 方法的调用中,第一个格式项 {0:D}
被 thatDate
的字符串表示形式;第二个格式项 {1}
被 item1
的字符串表示形式替换;第三个格式项 {2:C2}
被 item1.Value
的字符串表示形式替换。
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
thatDate, item1, item1.Value);
Console.WriteLine(result);
// The example displays output like the following if run on a system
// whose current culture is en-US:
// On 5/1/2009, the inventory of WidgetA was worth $107.44.
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.", _
thatDate, item1, item1.Value)
Console.WriteLine(result)
' The example displays output like the following if run on a system
' whose current culture is en-US:
' On 5/1/2009, the inventory of WidgetA was worth $107.44.
除了将格式项替换为其相应对象的字符串表示形式之外,格式项还可让你控制:
- 将对象表示为字符串的特定方法(如果对象实现 IFormattable 接口并支持格式字符串)。 为此,可在格式项的索引后加上
:
(冒号),后跟一个有效的格式字符串。 前面的示例执行此操作的方式是:格式化带有d
(短日期模式)格式字符串(例如,{0:d}
)的日期值,并格式化带有C2
格式字符串(例如,{2:C2}
)的数值,将数量表示为具有两位小数位数的货币值。 - 包含对象的字符串表示形式的字段的宽度以及该字段中字符串表现形式的对齐方式。 为此,可在格式项的索引后加上
,
(逗号),后跟字段宽度。 如果字段宽度为正值,则字段中的字符串为右对齐,如果字段宽度是负值,则为左对齐。 在下面的示例中,在由 20 个字符组成的字段中的日期值左对齐,而在由 11 个字符组成的字段中,带有一位小数的十进制值右对齐。DateTime startDate = new DateTime(2015, 8, 28, 6, 0, 0); decimal[] temps = { 73.452m, 68.98m, 72.6m, 69.24563m, 74.1m, 72.156m, 72.228m }; Console.WriteLine("{0,-20} {1,11}\n", "Date", "Temperature"); for (int ctr = 0; ctr < temps.Length; ctr++) Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps[ctr]); // The example displays the following output: // Date Temperature // // 8/28/2015 6:00 AM 73.5 // 8/29/2015 6:00 AM 69.0 // 8/30/2015 6:00 AM 72.6 // 8/31/2015 6:00 AM 69.2 // 9/1/2015 6:00 AM 74.1 // 9/2/2015 6:00 AM 72.2 // 9/3/2015 6:00 AM 72.2
Dim startDate As New Date(2015, 8, 28, 6, 0, 0) Dim temps() As Decimal = { 73.452, 68.98, 72.6, 69.24563, 74.1, 72.156, 72.228 } Console.WriteLine("{0,-20} {1,11}", "Date", "Temperature") Console.WriteLine() For ctr As Integer = 0 To temps.Length - 1 Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps(ctr)) Next ' The example displays the following output: ' Date Temperature ' ' 8/28/2015 6:00 AM 73.5 ' 8/29/2015 6:00 AM 69.0 ' 8/30/2015 6:00 AM 72.6 ' 8/31/2015 6:00 AM 69.2 ' 9/1/2015 6:00 AM 74.1 ' 9/2/2015 6:00 AM 72.2 ' 9/3/2015 6:00 AM 72.2
请注意,如果对齐字符串组件和格式字符串组件均存在,则前者位于后者之前(例如,
{0,-20:g}
)。
有关复合格式的更多信息,请参见 Composite Formatting 。
使用 ICustomFormatter 进行自定义格式设置
两种复合格式设置方法( String.Format(IFormatProvider, String, Object[]) 和 StringBuilder.AppendFormat(IFormatProvider, String, Object[]) )包括一个支持自定义格式设置的格式提供程序。 当调用其中一种格式设置方法时,该方法会将表示 Type 接口的 ICustomFormatter 对象传递到格式提供程序的 GetFormat 方法。 GetFormat 方法然后负责返回提供自定义格式设置功能的 ICustomFormatter 实现。
ICustomFormatter 接口具有一个方法 Format(String, Object, IFormatProvider) ,复合格式设置方法为复合格式字符串中的每一格式项自动调用一次该方法。 Format(String, Object, IFormatProvider) 方法具有三个参数:一个格式字符串(表示格式项中的 formatString
参数)、一个要设置格式的对象和一个提供格式设置服务的 IFormatProvider 对象。 通常,实现 ICustomFormatter 的类还会实现 IFormatProvider ,因此上述最后一个参数是对自定义格式设置类自身的引用。 该方法返回要设置格式的对象的带格式自定义字符串表示形式。 如果该方法无法设置对象的格式,则应返回空引用(在 Visual Basic 中为 Nothing
)。
下面的示例提供一个名为 ICustomFormatter 的 ByteByByteFormatter
实现,该实现将整数值显示为两位的十六进制值后跟一个空格的序列。
public class ByteByByteFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(string format, object arg,
IFormatProvider formatProvider)
{
if (! formatProvider.Equals(this)) return null;
// Handle only hexadecimal format string.
if (! format.StartsWith("X")) return null;
byte[] bytes;
string output = null;
// Handle only integral types.
if (arg is Byte)
bytes = BitConverter.GetBytes((Byte) arg);
else if (arg is Int16)
bytes = BitConverter.GetBytes((Int16) arg);
else if (arg is Int32)
bytes = BitConverter.GetBytes((Int32) arg);
else if (arg is Int64)
bytes = BitConverter.GetBytes((Int64) arg);
else if (arg is SByte)
bytes = BitConverter.GetBytes((SByte) arg);
else if (arg is UInt16)
bytes = BitConverter.GetBytes((UInt16) arg);
else if (arg is UInt32)
bytes = BitConverter.GetBytes((UInt32) arg);
else if (arg is UInt64)
bytes = BitConverter.GetBytes((UInt64) arg);
else
return null;
for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
output += String.Format("{0:X2} ", bytes[ctr]);
return output.Trim();
}
}
Public Class ByteByByteFormatter : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(formatType As Type) As Object _
Implements IFormatProvider.GetFormat
If formatType Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, arg As Object,
formatProvider As IFormatProvider) As String _
Implements ICustomFormatter.Format
If Not formatProvider.Equals(Me) Then Return Nothing
' Handle only hexadecimal format string.
If Not fmt.StartsWith("X") Then
Return Nothing
End If
' Handle only integral types.
If Not typeof arg Is Byte AndAlso
Not typeof arg Is Int16 AndAlso
Not typeof arg Is Int32 AndAlso
Not typeof arg Is Int64 AndAlso
Not typeof arg Is SByte AndAlso
Not typeof arg Is UInt16 AndAlso
Not typeof arg Is UInt32 AndAlso
Not typeof arg Is UInt64 Then _
Return Nothing
Dim bytes() As Byte = BitConverter.GetBytes(arg)
Dim output As String = Nothing
For ctr As Integer = bytes.Length - 1 To 0 Step -1
output += String.Format("{0:X2} ", bytes(ctr))
Next
Return output.Trim()
End Function
End Class
下面的示例使用 ByteByByteFormatter
类设置整数值的格式。 请注意, ICustomFormatter.Format 方法不止一次调用中第二个 String.Format(IFormatProvider, String, Object[]) 方法调用,并且默认值 NumberFormatInfo 因为,第三个方法调用中使用的提供程序。 ByteByByteFormatter.Format
方法无法识别 N0
格式字符串并返回空引用(在 Visual Basic 中为 Nothing
)的格式说明符。
public class Example
{
public static void Main()
{
long value = 3210662321;
byte value1 = 214;
byte value2 = 19;
Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
value1, value2, value1 & value2));
Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
}
}
// The example displays the following output:
// 00 00 00 00 BF 5E D1 B1
// 00 D6 And 00 13 = 00 12 (018)
// 3,210,662,321
Public Module Example
Public Sub Main()
Dim value As Long = 3210662321
Dim value1 As Byte = 214
Dim value2 As Byte = 19
Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X}", value)))
Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
value1, value2, value1 And value2)))
Console.WriteLine(String.Format(New ByteByByteFormatter(), "{0,10:N0}", value))
End Sub
End Module
' The example displays the following output:
' 00 00 00 00 BF 5E D1 B1
' 00 D6 And 00 13 = 00 12 (018)
' 3,210,662,321
相关主题
标题 | 定义 |
---|---|
Standard Numeric Format Strings | 描述用于创建数字值的常用字符串表示形式的标准格式字符串。 |
Custom Numeric Format Strings | 描述用于创建数字值的应用程序特定格式的自定义格式字符串。 |
Standard Date and Time Format Strings | 描述用于创建 DateTime 值的常用字符串表示形式的标准格式字符串。 |
Custom Date and Time Format Strings | 描述用于创建 DateTime 值的应用程序特定格式的自定义格式字符串。 |
标准 TimeSpan 格式字符串 | 描述用于创建时间间隔的常用字符串表示形式的标准格式字符串。 |
自定义 TimeSpan 格式字符串 | 描述用于创建时间间隔的应用程序特定格式的自定义格式字符串。 |
Enumeration Format Strings | 描述用于创建枚举值的字符串表示形式的标准格式字符串。 |
复合格式设置 | 描述如何将一个或多个设置了格式的值嵌入字符串。 然后该字符串可以显示在控制台上或被写至流。 |
执行格式设置操作 | 列出分步说明如何执行特定的格式设置操作的主题。 |
Parsing Strings | 描述如何将对象初始化为这些对象的字符串表示形式所描述的值。 分析是格式化的反向操作。 |
引用
System.IFormattable
System.IFormatProvider
System.ICustomFormatter
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论