c#开发 明日科技
2019-06-05 14:36:00 weixin_34357267 阅读数 16
17495666-f257c32c22bb893b.jpg

内容介绍

《零基础学C#》是一本针对零基础编程学习者全新研发的C#入门教程。从初学者角度出发,通过通俗易懂的语言、流行有趣的实例,详细地介绍了使用C语言进行程序开发需要掌握的知识和技术。全书共分16章,包括Visual Studio的安装、踏上C#开发的征程、必须学会的C#语法、流程控制语句、看似简单的字符串、面向对象程序设计、Windows交互式图形界面、数据访问技术、程序调试与异常处理、多线程编程技术以及五子棋大厅游戏等。书中所有知识都结合具体实例进行讲解,设计的程序代码给出了详细的注释,可以使读者轻松领会C#程序开发的精髓,快速提高开发技能。

本书通过大量实例及一个完整项目案例,帮助读者更好地巩固所学知识,提升能力;随书附赠的《小白实战手册》中给出了3个流行且实用的案例的详细开发流程,力求让学习者能学以致用,真正获得开发经验;附赠的光盘中给出视频讲解、实例及项目源码、代码查错器、练一练和动手纠错答案等,方便读者学习;书中设置了200多个二维码,扫描二维码观看视频讲解,解决学习疑难;不易理解的专业术语、代码难点只需手机扫描文字下方的e学码获得更多扩展解释,随时扫除学习障碍。

目录

第1 篇 基础知识

第1 章 宇宙第一IDE — Visual Studio

第2 章 踏上C# 开发的征程

第3 章 必须学会的C# 语法

第4 章 流程控制语句

第5 章 数组—批量数据处理

第6 章 看似简单的字符串

第7 章 面向对象程序设计

第2 篇 核心技术

第8 章 Windows 交互式图形界面

第9 章 Windows 控件—C/S 程序的基础...215

第10 章 数据访问技术

第11 章 程序调试与异常处理

第3 篇 高级应用

第12 章 I/O 数据流技术

第13 章 GDI+ 绘图应用

第14 章 Socket 网络编程

第15 章 多线程编程技术

第4 篇 项目实战

第16 章 五子棋大厅游戏

链接: https://pan.baidu.com/s/1ij2oebRZDZ5w8qK0ufwyIg 提取码: 8hbe

转载于:https://www.jianshu.com/p/e98a6f9c0a25

2018-09-10 22:51:58 txwtech 阅读数 2555

https://pan.baidu.com/s/1L8R28pFChWvwIjB_xeNEvA#list/path=%2F

ihwf

C#从入门到精通(第4版) 明日科技 随书视频光盘+源码[1.6G]

 

第1篇  基 础 知 识

 

第1章  初识C#及其开发环境

(  视频讲解:63分钟)

1.1  C#概述

1.1.1  C#语言及其特点

1.1.2  认识.NET Framework

1.1.3  C#与.NET框架

1.1.4  C#的应用领域

1.2  安装与卸载Visual Studio 2015

1.2.1  安装Visual Studio 2015系统的**条件

1.2.2  安装Visual Studio 2015

1.2.3  启动Visual Studio 2015

1.2.4  卸载Visual Studio 2015

1.3  熟悉Visual Studio 2015开发环境

1.3.1  创建项目

1.3.2  菜单栏

1.3.3  工具栏

1.3.4  解决方案资源管理器

1.3.5  “工具箱”窗口

1.3.6  “属性”窗口

1.3.7  “错误列表”窗口

1.3.8  “输出”窗口

1.4  小结

 

第2章  开始C#之旅

(  视频讲解:68分钟)

2.1  编写第一个C#程序

2.2  初识C#程序结构

2.2.1  命名空间

2.2.2  类

2.2.3  Main方法

2.2.4  标识符及关键字

2.2.5  C#语句

2.2.6  注释

2.3  程序编写规范

2.3.1  代码书写规则

2.3.2  命名规范

2.4  小结

2.5  动手纠错

 

第3章  变量与常量

(  视频讲解:148分钟)

3.1  变量的基本概念

3.2  变量的声明及赋值

3.2.1  声明变量

3.2.2  变量的赋值

3.2.3  变量的作用域

3.3  数据类型

3.3.1  值类型

3.3.2  引用类型

3.3.3  值类型与引用类型的区别

3.3.4  枚举类型

3.3.5  类型转换

3.4  常量

3.5  小结

3.6  实践与练习

3.7  动手纠错

 

第4章  表达式与运算符

(  视频讲解:98分钟)

4.1  表达式

4.2  运算符

4.2.1  算术运算符

4.2.2  赋值运算符

4.2.3  关系运算符

4.2.4  逻辑运算符

4.2.5  位运算符

4.2.6  其他特殊运算符

4.3  运算符优先级

4.4  小结

4.5  实践与练习

4.6  动手纠错

 

第5章  字符与字符串

(  视频讲解:127分钟)

5.1  字符类Char的使用

5.1.1  Char类概述

5.1.2  Char类的使用

5.1.3  转义字符

5.2  字符串类String的使用

5.2.1  字符串的声明及赋值

5.2.2  连接多个字符串

5.2.3  比较字符串

5.2.4  格式化字符串

5.2.5  截取字符串

5.2.6  分割字符串

5.2.7  插入和填充字符串

5.2.8  删除字符串

5.2.9  复制字符串

5.2.10  替换字符串

5.3  可变字符串类

5.3.1  StringBuilder类的定义

5.3.2  StringBuilder类的使用

5.3.3  StringBuilder类与String类的区别

5.4  小结

5.5  实践与练习

5.6  动手纠错

 

第6章  流程控制语句

(  视频讲解:109分钟)

6.1  条件判断语句

6.1.1  if语句

6.1.2  switch多分支语句

6.2  循环语句

6.2.1  while语句

6.2.2  do…while语句

6.2.3  for语句

6.2.4  foreach语句

6.3  跳转语句

6.3.1  break语句

6.3.2  continue语句

6.3.3  goto语句

6.3.4  return语句

6.4  小结

6.5  实践与练习

6.6  动手纠错

 

第7章  数组和集合

(  视频讲解:107分钟)

7.1  数组概述

7.2  一维数组的创建和使用

7.2.1  一维数组的创建

7.2.2  一维数组的初始化

7.2.3  一维数组的使用

7.3  二维数组的创建和使用

7.3.1  二维数组的创建

7.3.2  二维数组初始化

7.3.3  二维数组的使用

7.4  数组的基本操作

7.4.1  遍历数组

7.4.2  添加/删除数组元素

7.4.3  对数组进行排序

7.4.4  数组的合并与拆分

7.5  数组排序算法

7.5.1  冒泡排序

7.5.2  直接插入排序

7.5.3  选择排序法

7.6  ArrayList类

7.6.1  ArrayList类概述

7.6.2  ArrayList元素的添加

7.6.3  ArrayList元素的删除

7.6.4  ArrayList的遍历

7.6.5  ArrayList元素的查找

7.7  Hashtable(哈希表)

7.7.1  Hashtable概述

7.7.2  Hashtable元素的添加

7.7.3  Hashtable元素的删除

7.7.4  Hashtable的遍历

7.7.5  Hashtable元素的查找

7.8  小结

7.9  实践与练习

7.10  动手纠错

 

第8章  属性和方法

(  视频讲解:43分钟)

8.1  属性

8.1.1  属性概述

8.1.2  属性的使用

8.2  方法

8.2.1  方法的声明

8.2.2  方法的参数类型

8.2.3  方法的分类

8.2.4  方法的重载

8.2.5  Main方法

8.3  小结

8.4  实践与练习

8.5  动手纠错

 

第9章  结构和类

(  视频讲解:64分钟)

9.1  结构

9.1.1  结构概述

9.1.2  结构的使用

9.2  面向对象概述

9.2.1  对象

9.2.2  类

9.2.3  封装

9.2.4  继承

9.2.5  多态

9.3  类

9.3.1  类的概念

9.3.2  类的声明

9.3.3  构造函数和析构函数

9.3.4  对象的创建及使用

9.3.5  this关键字

9.3.6  类与对象的关系

9.4  类的面向对象特性

9.4.1  类的封装

9.4.2  类的继承

9.4.3  类的多态

9.5  小结

9.6  实践与练习

 

第2篇  核 心 技 术

第10章  Windows窗体

(  视频讲解:61分钟)

10.1  Form窗体

10.1.1  Form窗体的概念

10.1.2  添加和删除窗体

10.1.3  多窗体的使用

10.1.4  窗体的属性

10.1.5  窗体的显示与隐藏

10.1.6  窗体的事件

10.2  MDI窗体

10.2.1  MDI窗体的概念

10.2.2  如何设置MDI窗体

10.2.3  排列MDI子窗体

10.3  继承窗体

10.3.1  继承窗体的概念

10.3.2  创建继承窗体

10.3.3  在继承窗体中修改继承的控件属性

10.4  小结

10.5  实践与练习

 

第11章  Windows应用程序常用控件

(  视频讲解:93分钟)

11.1  控件概述

11.1.1  控件的分类及作用

11.1.2  控件命名规范

11.2  控件的相关操作

11.2.1  添加控件

11.2.2  对齐控件

11.2.3  锁定控件

11.2.4  删除控件

11.3  文本类控件

11.3.1  标签控件(Label控件)

11.3.2  按钮控件(Button控件)

11.3.3  文本框控件(TextBox控件)

11.3.4  有格式文本控件(RichTextBox控件)

11.4  选择类控件

11.4.1  下拉组合框控件(ComboBox控件)

11.4.2  复选框控件(CheckBox控件)

11.4.3  单选按钮控件(RadioButton控件)

11.4.4  数值选择控件(NumericUpDown控件)

11.4.5  列表控件(ListBox控件)

11.5  分组类控件

11.5.1  容器控件(Panel控件)

11.5.2  分组框控件(GroupBox控件)

11.5.3  选项卡控件(TabControl控件)

11.6  菜单、工具栏和状态栏控件

11.6.1  菜单控件(MenuStrip控件)

11.6.2  工具栏控件(ToolStrip控件)

11.6.3  状态栏控件(StatusStrip控件)

11.7  小结

11.8  实践与练习

 

第12章  Windows应用程序高级控件

(  视频讲解:71分钟)

12.1  ImageList控件(存储图像控件)

12.1.1  在ImageList控件中添加图像

12.1.2  在ImageList控件中移除图像

12.2  ListView控件(列表视图控件)

12.2.1  在ListView控件中添加移除项

12.2.2  选择ListView控件中的项

12.2.3  为ListView控件中的项添加图标

12.2.4  在ListView控件中启用平铺视图

12.2.5  为ListView控件中的项分组

12.3  TreeView控件(树控件)

12.3.1  添加和删除树节点

12.3.2  获取树控件中选中的节点

12.3.3  为树控件中的节点设置图标

12.4  DateTimePicker控件(日期控件)

12.4.1  使用DateTimePicker控件显示时间

12.4.2  使用DateTimePicker控件以自定义格式显示日期

12.4.3  返回DateTimePicker控件中选择的日期

12.5  MonthCalendar控件(月历控件)

12.5.1  更改MonthCalendar控件的外观

12.5.2  在MonthCalendar控件中显示多个月份

12.5.3  在MonthCalendar控件中以粗体显示特定日期

12.5.4  在MonthCalendar控件中选择日期范围

12.6  其他高级控件

12.6.1  使用ErrorProvider控件验证文本框输入

12.6.2  使用HelpProvider控件调用帮助文件

12.6.3  使用Timer控件设置时间间隔

12.6.4  使用ProgressBar控件显示程序运行进度条

12.7  小结

12.8  实践与练习

 

第13章  数据访问技术

(  视频讲解:84分钟)

13.1  数据库基础

13.1.1  数据库简介

13.1.2  SQL语言简介

13.1.3  数据库的创建及删除

13.1.4  数据表的创建及删除

13.1.5  简单SQL语句的应用

13.2  ADO.NET简介

13.3  连接数据库:Connection对象

13.3.1  Connection对象概述

13.3.2  连接数据库

13.3.3  关闭连接

13.4  执行SQL语句:Command对象

13.4.1  Command对象概述

13.4.2  设置数据源类型

13.4.3  执行SQL语句

13.5  读取数据:DataReader对象

13.5.1  DataReader对象概述

13.5.2  判断查询结果中是否有值

13.5.3  读取数据

13.6  数据适配器:DataAdapter对象

13.6.1  DataAdapter对象概述

13.6.2  填充DataSet数据集

13.6.3  更新数据源

13.7  数据集:DataSet对象

13.7.1  DataSet对象概述

13.7.2  合并DataSet内容

13.7.3  复制DataSet内容

13.8  小结

13.9  实践与练习

 

第14章  DataGridView数据控件

(  视频讲解:47分钟)

14.1  DataGridView控件概述

14.2  在DataGridView控件中显示数据

14.3  获取DataGridView控件中的当前单元格

14.4  直接在DataGridView控件中修改数据

14.5  当选中DataGridView控件中的行时显示不同的颜色

14.6  禁止在DataGridView控件中添加和删除行

14.7  使用Columns和Rows属性添加数据

14.8  小结

14.9  实践与练习

 

第15章  LINQ数据访问技术

(  视频讲解:62分钟)

15.1  LINQ基础

15.1.1  LINQ概述

15.1.2  使用var创建隐型局部变量

15.1.3  Lambda表达式的使用

15.1.4  LINQ查询表达式

15.2  使用LINQ操作SQL Server数据库

15.2.1  使用LINQ查询SQL Server数据库

15.2.2  使用LINQ管理SQL Server数据库

15.3  使用LINQ操作其他数据

15.3.1  使用LINQ操作数组和集合

15.3.2  使用LINQ操作DataSet数据集

15.3.3  使用LINQ操作XML

15.4  小结

15.5  实践与练习

 

第16章  程序调试与异常处理

(  视频讲解:40分钟)

16.1  程序调试概述

16.2  常用的程序调试操作

16.2.1  断点操作

16.2.2  开始执行

16.2.3  中断执行

16.2.4  停止执行

16.2.5  单步执行和逐过程执行

16.2.6  运行到指定位置

16.3  异常处理概述

16.4  异常处理语句

16.4.1  try…catch语句

16.4.2  throw语句

16.4.3  try…catch…finally语句

16.5  小结

16.6  实践与练习

 

第3篇  高 级 应 用

第17章  面向对象技术高级应用

(  视频讲解:41分钟)

17.1  抽象类与抽象方法

17.1.1  抽象类概述及声明

17.1.2  抽象方法概述及声明

17.1.3  抽象类与抽象方法的使用

17.2  接口

17.2.1  接口的概念及声明

17.2.2  接口的实现与继承

17.2.3  显式接口成员实现

17.2.4  抽象类与接口

17.3  密封类与密封方法

17.3.1  密封类概述及声明

17.3.2  密封方法概述及声明

17.3.3  密封类与密封方法的使用

17.4  小结

17.5  实践与练习

 

第18章  迭代器和分部类

(  视频讲解:20分钟)

18.1  迭代器

18.1.1  迭代器概述

18.1.2  迭代器的使用

18.2  分部类

18.2.1  分部类概述

18.2.2  分部类的使用

18.3  小结

18.4  实践与练习

 

第19章  泛型的使用

(  视频讲解:23分钟)

19.1  泛型概述

19.2  泛型的使用

19.2.1  类型参数T

19.2.2  泛型接口

19.2.3  泛型方法

19.3  小结

19.4  实践与练习

 

第20章  文件及数据流技术

(  视频讲解:83分钟)

20.1  System.IO命名空间

20.1.1  File类和Directory类

20.1.2  FileInfo类和DirectoryInfo类

20.2  文件基本操作

20.2.1  判断文件是否存在

20.2.2  创建文件

20.2.3  复制或移动文件

20.2.4  删除文件

20.2.5  获取文件的基本信息

20.3  文件夹的基本操作

20.3.1  判断文件夹是否存在

20.3.2  创建文件夹

20.3.3  移动文件夹

20.3.4  删除文件夹

20.3.5  遍历文件夹

20.4  数据流

20.4.1  流操作类介绍

20.4.2  文件流类

20.4.3  文本文件的写入与读取

20.4.4  二进制文件的写入与读取

20.5  小结

20.6  实践与练习

 

第21章  GDI 图形图像技术

(  视频讲解:72分钟)

21.1  GDI 绘图基础

21.1.1  GDI 概述

21.1.2  创建Graphics对象

21.1.3  创建Pen对象

21.1.4  创建Brush对象

21.2  基本图形的绘制

21.2.1  GDI 中的直线和矩形

21.2.2  GDI 中的椭圆、圆弧和扇形

21.2.3  GDI 中的多边形

21.3  GDI 绘图的应用

21.3.1  绘制柱形图

21.3.2  绘制折线图

21.3.3  绘制饼形图

21.4  小结

21.5  实践与练习

 

第22章  Windows打印技术

(  视频讲解:28分钟)

22.1  PageSetupDialog控件

22.2  PrintDialog控件

22.3  PrintDocument控件

22.4  PrintPreviewControl控件

22.5  PrintPreviewDialog控件

22.6  小结

22.7  实践与练习

 

第23章  网络编程技术

(  视频讲解:72分钟)

23.1  网络编程基础

23.1.1  System.Net命名空间

23.1.2  System.Net.Sockets命名空间

23.1.3  System.Net.Mail命名空间

23.1.4  POP3协议

23.2  开发网络应用程序

23.2.1  创建Web页面浏览器

23.2.2  局域网聊天程序

23.2.3  电子邮件的发送与接收

23.3  小结

23.4  实践与练习

 

第24章  注册表技术

(  视频讲解:21分钟)

24.1  注册表基础

24.1.1  Windows注册表概述

24.1.2  Registry和RegistryKey类

24.2  在C#中操作注册表

24.2.1  读取注册表中的信息

24.2.2  创建和修改注册表信息

24.2.3  删除注册表中的信息

24.3  小结

24.4  实践与练习

 

第25章  线程的使用

(  视频讲解:30分钟)

25.1  线程简介

25.1.1  单线程简介

25.1.2  多线程简介

25.2  线程的基本操作

25.2.1  Thread类

25.2.2  创建线程

25.2.3  线程的挂起与恢复

25.2.4  线程休眠

25.2.5  终止线程

25.2.6  线程的优先级

25.2.7  线程同步

25.3  小结

25.4  实践与练习

 

第4篇  项 目 实 战

第26章  企业人事管理系统

(  视频讲解:114分钟)

26.1  系统分析

26.1.1  需求分析

26.1.2  可行性分析

26.1.3  编写项目计划书

26.2  系统设计

26.2.1  系统目标

26.2.2  系统功能结构

26.2.3  系统业务流程图

26.2.4  系统编码规范

26.3  系统运行环境

26.4  数据库与数据表设计

26.4.1  数据库分析

26.4.2  创建数据库

26.4.3  创建数据表

26.4.4  数据表逻辑关系

26.5  创建项目

26.6  公共类设计

26.6.1  MyMeans公共类

26.6.2  MyModule公共类

26.7  登录模块设计

26.7.1  设计登录窗体

26.7.2  按Enter键时移动鼠标焦点

26.7.3  登录功能的实现

26.8  系统主窗体设计

26.8.1  设计菜单栏

26.8.2  设计工具栏

26.8.3  设计导航菜单

26.8.4  设计状态栏

26.9  人事档案管理模块设计

26.9.1  设计人事档案管理窗体

26.9.2  添加/修改人事档案信息

26.9.3  删除人事档案信息

26.9.4  单条件查询人事档案信息

26.9.5  逐条查看人事档案信息

26.9.6  将人事档案信息导出为Word文档

26.9.7  将人事档案信息导出为Excel表格

26.10  人事资料查询模块设计

26.10.1  设计人事资料查询窗体

26.10.2  多条件查询人事资料

26.11  通讯录模块设计

26.11.1  设计通讯录窗体

26.11.2  添加/修改通讯录信息

26.11.3  删除通讯录信息

26.11.4  查询通讯录信息

26.12  用户设置模块设计

26.12.1  设计用户设置窗体

26.12.2  添加/修改用户信息

26.12.3  删除用户基本信息

26.12.4  设置用户操作权限

26.13  数据库维护模块设计

26.13.1  设计数据库维护窗体

26.13.2  备份数据库

26.13.3  还原数据库

26.14  运行项目

26.15  开发的常见问题与解决

26.15.1  程序为什么会无法运行

26.15.2  为什么无法添加职工基本信息

26.15.3  选择职工头像时出现异常怎么办

26.15.4  数据库还原不成功应该如何解决

26.16  小结

附录A

C#开发
2011-01-03 12:37:02 iteye_6444 阅读数 181

   此文要说的'知易营养健康系统'是b/s架构,用.net开发的应用程序,这里也只是说几点值得做类似项目或功能时需注意、借鉴的地方。

        图1:

       1. 如上图是‘营养计算器’页面,——看页面(http://zhiyi2010.s242.iis3.com/calculator/calory.aspx)就可以知道其大概的功能——主要包括:食物信息检索、添加食物到餐别中并分析所有餐别中食物各项营养素含量,整个页面的功能代码量主要集中在jquery+Ajax的运用,js代码量大概在1000行左右(大家可能会问:这个页面的功能有这么复杂,需要写这么多的js代码吗,——这个主要是我的实现方式的考虑所决定:想给用户比较好的用户体验,快速响应,后台只是做必要的数据处理),而且js代码还有待优化精简,下面贴出的是 其中的一个核心方法,更多的应用 如:鼠标点击出弹出 添加/修改 食物重量框,jquey中一些方法的使用...

    

function AddToCanBox(foodId,foodName,deHeat,isDefaultAdd,addWeight) 2     { 3         var can=GetHidCurrentCan(); 4         var canValue=GetHidCanValue(can); 5         var tempArray=new Array();//食物项数组 6         var foodProArray=new Array();//食物属性数组 7          8         var Weight_now=0; 9         var foodProStr="";10         var isHased=false;//标识此食物是否已存在11           12         var deWeight=100;13         addWeight=GetZhengshu(addWeight);14         addWeight=Round_number(addWeight);15         16         if(canValue!=null && canValue!="")//如果已存在此餐类别的食物17         {18             foodItemArray=canValue.split("|");19             var foodItem=new Array();20             var findId=null;21 22             for(var i in foodItemArray)23             {24                 foodItem=foodItemArray[i];//得到是的:1,232,34,45...字符串25                 if(foodItem!="" && foodItem!=null)26                 {27                     foodProArray=foodItem.split(",");28                     if(foodProArray!=null && foodProArray.length>0)29                     {30                         findId=foodProArray[0];//foodId31 32                         if(findId==foodId)//如果此食物已存在33                         {34                            Weight_now=foodProArray[3];//nowWeight35                            Weight_now=isDefaultAdd?(Number(Weight_now)+Number(deWeight)):(Number(Weight_now)+Number(addWeight));36                            Weight_now=Round_number(Weight_now);37                            foodProArray[3]=Weight_now;//修改其Weight_now38                            isHased=true;39                         }40                         foodProStr=foodProArray.join(",");41                         tempArray.push(foodProStr);//存放一个餐别下的食物信息42                     }43                 }44             }45         }46    47         foodProStr="";48         if(!isHased)//新添加的49         {50                foodProArray=new Array();51                foodProArray.push(foodId);52                foodProArray.push(foodName);53                foodProArray.push(deHeat);54 55                Weight_now=isDefaultAdd?deWeight:(addWeight==0?deWeight:addWeight);56                Weight_now=Round_number(Weight_now);57                foodProArray.push(Weight_now);58 59                foodProStr=foodProArray.join(",");60                tempArray.push(foodProStr);//存放一个餐别下的食物信息61         }62         63         DoAjax(tempArray,can,foodProStr,"");64     }

 

     2.滑动块等效果的实现.

   

        如上图,具体实现js代码,这里就不再贴出,需要的朋友可以直接下载参考使用:http://zhiyi2010.s242.iis3.com/calculator/energyloss.aspx

      3.立体柱状图的实现,效果如下:

     

   

   大家看图片就可以知道使用效果还不错,使用的是‘ FusionChart ’ flash 柱状图控件,其特点是:方便易用,且可以很好的使用ajax实现不同的条件显示(后台response

 输出xml),具体效果大家可以 登录网站  http://zhiyi2010.s242.iis3.com 注册会员后 在'营养足迹'里看到,有需要 这方面应用或学习的朋友,可以加我QQ(1030365071),即会给你

 emo,并互相学习和交流!

<script type="text/javascript"></script>

 

 

2018-03-19 20:57:41 lindexi_gd 阅读数 11593

本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道,如果觉得我在骗你,那么请看看下面

因为C#在微软的帮助,已经从原来很简单的,到现在的很好用。在10多年,很少人知道微软做了哪些,我在网上找了很多大神的博客,然后和很多大神聊天,知道了一些科技,所以就在这里说。如果大家看到这个博客里面没有的科技,请告诉我

无限级判断空

在 C# 6.0 可以使用??判断空,那么就可以使用下面代码

            var v1 = "123";
            string v2 = null;
            string v3 = null;

            var v = v1 ?? v2 ?? v3;

实际上可以无限的使用??判断前面一个函数为空,那么问题来了,下面的代码输出的是多少?

var n = 2 + foo?.N ?? 1;

上面代码的 foo 就是空的,那么 n 是多少?是 1 还是 2 还是 3 还是空?

想要了解这道题的推导过程请看C# 高级面试题 里面写了很多老司机都不一定能解出

using 省略长的定义

例如有这个代码,使用了很多的 List ,里面有很多定义

var foo =
                new System.Collections.Generic.Dictionary<
                    System.Collections.Generic.List<System.Collections.Generic.List<string>>, string>();

可以看到需要写很多代码,如果这个值作为参数,才是可怕。

一个简单的方法是使用 using HvcnrclHnlfk= System.Collections.Generic.Dictionary<System.Collections.Generic.List<System.Collections.Generic.List<string>>,string>; ,这个文件里的所有定义都可以使用 using 后面的值可以代替。

var foo = new HvcnrclHnlfk();

辣么大

实际上我有些不好意思,好像刚刚说的都是大家都知道的,那么我就要开始写大家很少知道

          Func<string,string, EventHandler> foo = (x, y) => (s, e) =>
            {
                var button = (Button) s;
                button.Left = x;
                button.Top = y;
            };

            Button1.Click += foo(0, -1);

看一下就知道这个定义可以做什么

当然使用委托可是会出现这个问题,请问下面的代码实际调用的是哪个委托,下面代码的 a 和 b 和 c 都是 Action 委托,同时都不是空的

((a + b + c) - (a + c))();

冲突的类型

如果遇到两个命名空间相同的类型,很多时候都是把命名空间全写

var webControl = new System.Web.UI.WebControls.Control();
var formControl = new System.Windows.Forms.Control();

如果经常使用这两个控件,那么就需要写空间,代码很多,但是微软给了一个坑,使用这个可以不用写空间

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control webControl = new web::Control();
win::Control formControl = new win::Control();

参见:https://stackoverflow.com/a/9099/6116637

extern alias

如果使用了两个 dll ,都有相同命名空间和类型,那么如何使用指定的库

//a.dll

namespace F
{
	public class Foo
	{

	}
}

//b.dll

namespace F
{
	public class Foo
	{
		
	}
}

这时就可以使用 extern alias

参见:C#用extern alias解决两个assembly中相同的类型全名 - fresky - 博客园

字符串

大家看到了 C# 6.0 的$,是不是可以和@一起?

            var str = "kktpqfThiq";
            string foo = $@"换行
{str}";

注意两个的顺序,反过来直接告诉你代码不能这样写

表达式树获取函数命名

定义一个类,下面通过表达式树从类获得函数命名

    class Foo
    {
        public void KzcSevfio()
        {
        }
    }
       static void Main(string[] args)
        {
            GetMethodName<Foo>(foo => foo.KzcSevfio());
        }

        private static void GetMethodName<T>(Expression<Action<T>> action) where T : class
        {
            if (action.Body is MethodCallExpression expression)
            {
                Console.WriteLine(expression.Method.Name);
            }
        }

这样就可以拿到函数的命名

特殊关键字

实际上有下面几个关键字是没有文档,可能只有垃圾微软的编译器才知道

__makeref

__reftype

__refvalue

__arglist

不过在 C# 7.2 都可以使用其他的关键字做到一些,详细请看我的 C# 7.0 博客

DebuggerDisplay

如果想要在调试的时候,鼠标移动到变量显示他的信息,可以重写类的 ToString

    public sealed class Foo
    {
        public int Count { get; set; }

        public override string ToString()
        {
            return Count.ToString();
        }
    }

在这里插入图片描述

但是如果 ToString 被其他地方用了,如何显示?

垃圾微软告诉大家,使用 DebuggerDisplay 特性

    [DebuggerDisplay("{DebuggerDisplay}")]
    public sealed class Foo
    {
        public int Count { get; set; }

        private string DebuggerDisplay => $"(count {Count})";
    }

他可以使用私有的属性、字段,使用方法很简单

参见Using the DebuggerDisplay Attribute

使用 Unions (C++ 一样的)

如果看到 C++ 可以使用内联,不要说 C# 没有,实际上也可以使用 FieldOffset ,请看下面

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

这时就定义了int变量,修改他就是修改其他的三个

     static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

这时会输出

2147483647
FF FF FF 7F
65535

接口默认方法

实际上可以给接口使用默认方法,使用的方式

public static void Foo(this IF1 foo)
{
     //实际上大家也看到是如何定义
}

数字格式

string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)

参见:自定义数字格式字符串

stackalloc

实际上很多人都不知道这个,这是不安全代码,从栈申请空间

int* block = stackalloc int[100]; 

参见:stackalloc

调用堆栈

如果需要获得调用方法的堆栈,可以使用这个文章的方法

  class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
        }
    }

    public sealed class Foo
    {
        public void F1()
        {
            F2();
        }

        void F2()
        {
            var stackTrace = new StackTrace();
            var n = stackTrace.FrameCount;
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine(stackTrace.GetFrame(i).GetMethod().Name);
            }
        }
    }

输出

F2
F1

参见:WPF 判断调用方法堆栈

指定编译

如果使用 Conditional 可以让代码在指定条件不使用,我写了这个代码,在 Release 下就不会使用 F2

    public sealed clas Foo
    {
        public Foo F1()
        {
            Console.WriteLine("进入F1");
            return this;
        }

        [Conditional("DEBUG")]
        public void F2()
        {
            Console.WriteLine("F2");
        }
    }

简单让代码跑一下

        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
            foo.F2();
        }

结果是什么,大家也知道,在 Debug 和 Release 输出是不相同。但是这么简单的怎么会在这里说,请大家看看这个代码输出什么

     static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1().F2();
        }

实际上在 Release 下什么都不会输出,F1 不会被执行

true 判断

下面写个见鬼的代码

            var foo = new Foo(10);

            if (foo)
            {
                Console.WriteLine("我的类没有继承 bool ,居然可以这样写");
            }

没错 Foo 没有继承 bool 居然可以这样写

实际上就是重写 true ,请看代码

    public class Foo
    {
        public Foo(int value)
        {
            _count = value;
        }

        private readonly int _count;

        public static bool operator true(Foo mt)
        {
            return mt._count > 0;
        }

        public static bool operator false(Foo mt)
        {
            return mt._count < 0;
        }
    }

是不是觉得很多有人这样写,下面让大家看一个很少人会知道的科技,感谢walterlv

重写运算返回

很少人知道实际上重写 == 可以返回任意的类型,而不是只有 bool ,请看下面代码

在这里插入图片描述

是可以编译通过的,因为我重写运算

   class Foo
    {
        public int Count { get; set; }
     
        public static string operator ==(Foo f1, Foo f2)
        {
            if (f1?.Count == f2?.Count)
            {
                return "lindexi";
            }

            return "";
        }

        public static string operator !=(Foo f1, Foo f2)
        {
            return "";
        }
    }

可以重写的运算很多,返回值可以自己随意定义。

await 任何类型

await "林德熙逗比";

await "不告诉你";

这个代码是可以编译通过的,但是只有在我的设备,然后看了这个博客,可能你也可以在你的设备编译

其实 await 是可以写很多次的,如下面代码

await await await await await await await await await await await await await await await await await await await await await await await "林德熙逗比";

变量名使用中文

实际上在C#支持所有 Unicode ,所以变量名使用中文也是可以的,而且可以使用特殊的字符

        public string H\u00e5rføner()
        {
            return "可以编译";
        }


在这里插入图片描述

if this == null

一般看到下面的代码都觉得是不可能

if (this == null) Console.WriteLine("this is null");

如果在 if 里面都能使用 this == null 成立,那么一定是vs炸了。实际上这个代码还是可以运行。

在一般的函数,如 Foo ,在调用就需要使用f.Foo()的方法,方法里 this 就是 f ,如果 f == null 那么在调用方法就直接不让运行,如何到方法里的判断

f.Foo(); //如果 f 为空,那么这里就不执行

void Foo()
{
   // 如果 this 为空,怎么可以调用这个方法
   if (this == null) Console.WriteLine("this is null");
}

实际上是可以做的,请看(C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切 - walterlv

如上面博客,关键在修改callvirtcall,直接修改 IL 可以做出很多特殊的写法。

那么这个可以用在哪里?可以用在防止大神反编译,如需要使用下面逻辑

//执行的代码

//不执行的代码
if(true)
{
   //执行的代码
}
else
{
   //不执行的代码 
}

但是直接写 true 很容易让反编译看到不使用代码,而且在优化代码会被去掉,所以可以使用下面代码

if(this == null)
{
   //执行的代码
}
else
{
   //不执行的代码 
}

实际在微软代码也是这样写,点击string可以看到微软代码

重载的运算符

实际上我可以将 null 强转某个类,创建一个新的对象,请看代码

Fantastic fantastic = (FantasticInfo) null;
fantastic.Foo();

这里的 FantasticInfo 和 Fantastic 没有任何继承关系,而且调用 Foo 不会出现空引用,也就是 fantastic 是从一个空的对象创建出来的。

是不是觉得上面的科技很黑,实际原理没有任何黑的科技,请看代码

    public class Fantastic
    {
        private Fantastic()
        {
        }

        public static implicit operator Fantastic(FantasticInfo value) => new Fantastic();

        public void Foo()
        {
        }
    }

    public class FantasticInfo
    {
    }

通过这个方式可以让开发者无法直接创建 Fantastic 类,而且在不知道 FantasticInfo 的情况无法创建 Fantastic 也就是让大家需要了解 FantasticInfo 才可以通过上面的方法创建,具体请看只有你能 new 出来!.NET 隐藏构造函数的 n 种方法(Builder Pattern / 构造器模式) - walterlv

课件链接: https://r302.cc/J4gxOX

当然还有新的 C# 7.0C# 8.0 的新的语法

欢迎加入 dotnet 职业技术学院 https://t.me/dotnet_campus 使用 Telegram 方法请看 如何使用 Telegram

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

2018-12-25 01:17:00 weixin_34101229 阅读数 12
原文:C# 很少人知道的科技

版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问。如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客。本文地址 https://blog.csdn.net/lindexi_gd/article/details/79617425

本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道,如果觉得我在骗你,那么请看看下面

因为C#在微软的帮助,已经从原来很简单的,到现在的很好用。在10多年,很少人知道微软做了哪些,我在网上找了很多大神的博客,然后和很多大神聊天,知道了一些科技,所以就在这里说。如果大家看到这个博客里面没有的科技,请告诉我。

无限级判断空

在 C# 6.0 可以使用??判断空,那么就可以使用下面代码

            var v1 = "123";
            string v2 = null;
            string v3 = null;

            var v = v1 ?? v2 ?? v3;

实际上可以无限的使用??

using 省略长的定义

例如有这个代码,使用了很多的 List ,里面有很多定义

var foo =
                new System.Collections.Generic.Dictionary<
                    System.Collections.Generic.List<System.Collections.Generic.List<string>>, string>();

可以看到需要写很多代码,如果这个值作为参数,才是可怕。

一个简单的方法是使用 using HvcnrclHnlfk= System.Collections.Generic.Dictionary<System.Collections.Generic.List<System.Collections.Generic.List<string>>,string>; ,这个文件里的所有定义都可以使用 using 后面的值可以代替。

var foo = new HvcnrclHnlfk();

辣么大

实际上我有些不好意思,好像刚刚说的都是大家都知道的,那么我就要开始写大家很少知道

          Func<string,string, EventHandler> foo = (x, y) => (s, e) =>
            {
                var button = (Button) s;
                button.Left = x;
                button.Top = y;
            };

            Button1.Click += foo(0, -1);

看一下就知道这个定义可以做什么

冲突的类型

如果遇到两个命名空间相同的类型,很多时候都是把命名空间全写

var webControl = new System.Web.UI.WebControls.Control();
var formControl = new System.Windows.Forms.Control();

如果经常使用这两个控件,那么就需要写空间,代码很多,但是微软给了一个坑,使用这个可以不用写空间

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control webControl = new web::Control();
win::Control formControl = new win::Control();

参见:https://stackoverflow.com/a/9099/6116637

extern alias

如果使用了两个 dll ,都有相同命名空间和类型,那么如何使用指定的库

//a.dll

namespace F
{
	public class Foo
	{

	}
}

//b.dll

namespace F
{
	public class Foo
	{
		
	}
}

这时就可以使用 extern alias

参见:C#用extern alias解决两个assembly中相同的类型全名 - fresky - 博客园

字符串

大家看到了 C# 6.0 的$,是不是可以和@一起?

            var str = "kktpqfThiq";
            string foo = $@"换行
{str}";

注意两个的顺序,反过来直接告诉你代码不能这样写

表达式树获取函数命名

定义一个类,下面通过表达式树从类获得函数命名

    class Foo
    {
        public void KzcSevfio()
        {
        }
    }
       static void Main(string[] args)
        {
            GetMethodName<Foo>(foo => foo.KzcSevfio());
        }

        private static void GetMethodName<T>(Expression<Action<T>> action) where T : class
        {
            if (action.Body is MethodCallExpression expression)
            {
                Console.WriteLine(expression.Method.Name);
            }
        }

这样就可以拿到函数的命名

特殊关键字

实际上有下面几个关键字是没有文档,可能只有垃圾微软的编译器才知道

__makeref

__reftype

__refvalue

__arglist

不过在 C# 7.2 都可以使用其他的关键字做到一些,详细请看我的 C# 7.0 博客

DebuggerDisplay

如果想要在调试的时候,鼠标移动到变量显示他的信息,可以重写类的 ToString

    public sealed class Foo
    {
        public int Count { get; set; }

        public override string ToString()
        {
            return Count.ToString();
        }
    }

在这里插入图片描述

但是如果 ToString 被其他地方用了,如何显示?

垃圾微软告诉大家,使用 DebuggerDisplay 特性

    [DebuggerDisplay("{DebuggerDisplay}")]
    public sealed class Foo
    {
        public int Count { get; set; }

        private string DebuggerDisplay => $"(count {Count})";
    }

他可以使用私有的属性、字段,使用方法很简单

参见Using the DebuggerDisplay Attribute

使用 Unions (C++ 一样的)

如果看到 C++ 可以使用内联,不要说 C# 没有,实际上也可以使用 FieldOffset ,请看下面

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

这时就定义了int变量,修改他就是修改其他的三个

     static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

这时会输出

2147483647
FF FF FF 7F
65535

接口默认方法

实际上可以给接口使用默认方法,使用的方式

public static void Foo(this IF1 foo)
{
     //实际上大家也看到是如何定义
}

数字格式

string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)

参见:自定义数字格式字符串

stackalloc

实际上很多人都不知道这个,这是不安全代码,从栈申请空间

int* block = stackalloc int[100]; 

参见:stackalloc

调用堆栈

如果需要获得调用方法的堆栈,可以使用这个文章的方法

  class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
        }
    }

    public sealed class Foo
    {
        public void F1()
        {
            F2();
        }

        void F2()
        {
            var stackTrace = new StackTrace();
            var n = stackTrace.FrameCount;
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine(stackTrace.GetFrame(i).GetMethod().Name);
            }
        }
    }

输出

F2
F1

参见:WPF 判断调用方法堆栈

指定编译

如果使用 Conditional 可以让代码在指定条件不使用,我写了这个代码,在 Release 下就不会使用 F2

    public sealed class Foo
    {
        public Foo F1()
        {
            Console.WriteLine("进入F1");
            return this;
        }

        [Conditional("DEBUG")]
        public void F2()
        {
            Console.WriteLine("F2");
        }
    }

简单让代码跑一下

        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1();
            foo.F2();
        }

结果是什么,大家也知道,在 Debug 和 Release 输出是不相同。但是这么简单的怎么会在这里说,请大家看看这个代码输出什么

     static void Main(string[] args)
        {
            var foo = new Foo();
            foo.F1().F2();
        }

实际上在 Release 下什么都不会输出,F1 不会被执行

true 判断

下面写个见鬼的代码

            var foo = new Foo(10);

            if (foo)
            {
                Console.WriteLine("我的类没有继承 bool ,居然可以这样写");
            }

没错 Foo 没有继承 bool 居然可以这样写

实际上就是重写 true ,请看代码

    public class Foo
    {
        public Foo(int value)
        {
            _count = value;
        }

        private readonly int _count;

        public static bool operator true(Foo mt)
        {
            return mt._count > 0;
        }

        public static bool operator false(Foo mt)
        {
            return mt._count < 0;
        }
    }

是不是觉得很多有人这样写,下面让大家看一个很少人会知道的科技,感谢walterlv

重写运算返回

很少人知道实际上重写 == 可以返回任意的类型,而不是只有 bool ,请看下面代码

是可以编译通过的,因为我重写运算

   class Foo
    {
        public int Count { get; set; }
     
        public static string operator ==(Foo f1, Foo f2)
        {
            if (f1?.Count == f2?.Count)
            {
                return "lindexi";
            }

            return "";
        }

        public static string operator !=(Foo f1, Foo f2)
        {
            return "";
        }
    }

可以重写的运算很多,返回值可以自己随意定义。

await 任何类型

await "林德熙逗比";

await "不告诉你";

这个代码是可以编译通过的,但是只有在我的设备,然后看了这个博客,可能你也可以在你的设备编译

变量名使用中文

实际上在C#支持所有 Unicode ,所以变量名使用中文也是可以的,而且可以使用特殊的字符

        public string H\u00e5rføner()
        {
            return "可以编译";
        }

在这里插入图片描述

if this == null

一般看到下面的代码都觉得是不可能

if (this == null) Console.WriteLine("this is null");

如果在 if 里面都能使用 this == null 成立,那么一定是vs炸了。实际上这个代码还是可以运行。

在一般的函数,如 Foo ,在调用就需要使用f.Foo()的方法,方法里 this 就是 f ,如果 f == null 那么在调用方法就直接不让运行,如何到方法里的判断

f.Foo(); //如果 f 为空,那么这里就不执行

void Foo()
{
   // 如果 this 为空,怎么可以调用这个方法
   if (this == null) Console.WriteLine("this is null");
}

实际上是可以做的,请看(C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切 - walterlv

如上面博客,关键在修改callvirtcall,直接修改 IL 可以做出很多特殊的写法。

那么这个可以用在哪里?可以用在防止大神反编译,如需要使用下面逻辑

//执行的代码

//不执行的代码
if(true)
{
   //执行的代码
}
else
{
   //不执行的代码 
}

但是直接写 true 很容易让反编译看到不使用代码,而且在优化代码会被去掉,所以可以使用下面代码

if(this == null)
{
   //执行的代码
}
else
{
   //不执行的代码 
}

实际在微软代码也是这样写,点击string可以看到微软代码

重载的运算符

实际上我可以将 null 强转某个类,创建一个新的对象,请看代码

Fantastic fantastic = (FantasticInfo) null;
fantastic.Foo();

这里的 FantasticInfo 和 Fantastic 没有任何继承关系,而且调用 Foo 不会出现空引用,也就是 fantastic 是从一个空的对象创建出来的。

是不是觉得上面的科技很黑,实际原理没有任何黑的科技,请看代码

    public class Fantastic
    {
        private Fantastic()
        {
        }

        public static implicit operator Fantastic(FantasticInfo value) => new Fantastic();

        public void Foo()
        {
        }
    }

    public class FantasticInfo
    {
    }

通过这个方式可以让开发者无法直接创建 Fantastic 类,而且在不知道 FantasticInfo 的情况无法创建 Fantastic 也就是让大家需要了解 FantasticInfo 才可以通过上面的方法创建,具体请看只有你能 new 出来!.NET 隐藏构造函数的 n 种方法(Builder Pattern / 构造器模式) - walterlv

课件链接: https://r302.cc/J4gxOX

欢迎加入 dotnet 职业技术学院 https://127.0.0.1/dotnet_campus 使用 Telegram 方法请看 如何使用 Telegram

我搭建了自己的博客 https://lindexi.gitee.io/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

C# 很少人知道的科技

阅读数 20

本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道,如果觉得我在骗你,那么请看看下面。目录无限级判断空using省略长的定义辣么大冲突的类型externalias字符串表达式树获取函数命名特殊关键字DebuggerDisplay使用Unions(C++一样的)接口默认方法数字格式stackalloc调用堆栈指定编译tru...

博文 来自: weixin_33729196

C#开发OCX控件之开发

阅读数 500

在C#中,其实没有OCX控件一说,相对应的只是COM组件,编译后也是.DLL,而不是.ocx.所以在C#中,在创建项目时只能创建类库项目。 然后就是具体的代码开发。(略) 要使组件成为能被网页脚本调用的OCX控件,在开发时,要注意以下几点: 1、必须要为将发布OCX控件的主类设置GUID码。该码在创建类库时,C#会自动生成一个(你可以使用,也可以重新生成),并存储在AssemblyIn

博文 来自: u011378394

C#开发之Socket网络编程

阅读数 599

1、TCP/IP层次模型当然这里我们只讨论重要的四层01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用。http协议在应用层运行。02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证。03,网络层(Ne

博文 来自: yutao929

C#开发编码规范

阅读数 230

  Pascal大小写形式——所有单词第一个字母大写,其他字母小写。Camel大小写形式——除了第一个单词,所有单词第一个字母大写,其他字母小写。类名使用Pascal大小写形式publicclassHelloWorld{ …}方法使用Pascal大小写形式publicclassHelloWorld{ voidSayHello(strin

博文 来自: wanlixingzhe2008

C#开发命名规范

阅读数 164

声明:本文为转载,非原创,如有侵权,请告知,本人会尽快删除。原文地址:http://blog.csdn.net/chenhongwu666/article/details/35354247学习C#之初,始终不知道怎么命名比较好,很多时候无从命名,终于有一天我整理了一份命名规范文档,自此我就是按照这个命名规范书写代码,整洁度无可言表,拙劣之处请大家斧正,愚某虚心接受,如有

博文 来自: zhd18
没有更多推荐了,返回首页