集合类型

数组

数组需要注意的就是多维数组和数组的数组之间的区别,如下:

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
//一维数组
int[] a1 = new int[];
int[] a2 = {, , , , }; //取最后一项
int i1 = a1[]; //二维数组
int[,] a3 = new int[, ];
int[,] a4 = {{, , }, {, , }}; //取最后一项
int i2 = a3[, ]; //数组的数组
int[][] a5 = new int[][];
int[][] a6 = {new int[] {, , }, new int[] {, }}; //取最后一项
int i3 = a6[][];
}
}
}

多维数组,每个子数组的长度必须一致;

数组的数组,每个子数组的长度可以不一致;

集合

  • ArrayList 可添加任意类型的列表,非泛型;
  • List 支持指定类型的列表,泛型;
  • HashTable 键和值都可以添加任意类型的哈希表,非泛型;
  • Dictionary 键和值都必须指定类型的哈希表,泛型;
  • ConcurrentDictionary 是线程安全的哈希表类,泛型;

类与结构体的区别

  • 定义类使用class,定义结构体使用struct。
  • 结构体不能对字段进行初始化,类可以。
  • 如果没有为类定义构造函数,则C#会自动定义一个无参的构造函数,如果定义了构造函数则不会自动定义无参的构造函数。而结构体无论是否定义构造函数都会自动添加一个无参的构造函数。
  • 结构体不能定义一个无参的构造函数,可以定义有参数的构造函数。类则无此限制。
  • 在结构体的有参构造函数中,必须为所有的字段进行赋值。
  • 创建结构体不使用new。
  • 结构体不能继承结构体或类但可以实现接口,类不能继承结构体。
  • 类是引用类型,结构体是值类型。
  • 结构体不能定义析构函数,类可以。
  • 结构体不能使用abstract和sealed关键字,类可以。

命名空间

命名空间不需要声明,直接namespace XXX就创建了一个名称为XXX的命名空间,也没有public,private之类的标识符。

namespace 关键字用于声明一个范围。此命名空间范围允许您组织代码并为您提供了创建全局唯一类型的方法。

无论您是否在 C# 源文件中显式声明了命名空间,编译器都会添加一个默认的命名空间。该未命名的命名空间(有时称为全局命名空间)存在于每一个文件中。全局命名空间中的任何标识符都可用于命名的命名空间中。

命名空间隐式具有公共访问权,并且这是不可修改的。有关可以分配给命名空间中的元素的访问修饰符的讨论,请参见访问修饰符(C# 参考)。

在两个或更多的声明中定义一个命名空间是可以的。

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
//相同命名空间下的 Test
Test test1 = new Test();
test1.Func("hello namespace"); //全局下的 Test
global::Test test2 = new global::Test();
Console.WriteLine(test2.Func()); // Develop 命名空间下的 Test
Develop.Test test3 = new Develop.Test();
Console.WriteLine(test3.Func(, )); Console.Read();
}
} public class Test
{
public void Func(string info)
{
Console.WriteLine(info);
}
}
} namespace Develop
{
public class Test
{
public int Func(int a, int b)
{
return a + b;
}
}
} public class Test
{
public string Func()
{
return "I`m in default namespace!";
}
}

运行结果如下:

 hello namespace
I`m in default namespace!

global标识符

global表示根命名空间。

如果我们定义的类名在默认命名空间中或者类名和其它命名空间一致则可以使用global标识一下该类。

静态类

静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量。在声明一个类时使用static关键字,具有两个方面的意义:首先,它防止程序员写代码来实例化该静态类;其次,它防止在类的内部声明任何实例字段或方法。

静态类的声明方式如下:

 public static class MyClass
{
//静态构造函数
static MyClass()
{}
}

静态类有一下几个特点:

  1. 仅包含静态成员;
  2. 无法实例化;
  3. 是密封的;
  4. 不能包含实例构造函数;

静态类和私有构造函数的区别

程序员必须声明一个私有构造器。私有构造器禁止开发者在类的范围之外实例化类的实例。使用私有构造器的效果与使用静态类的效果非常相似。两者的区别在于,私有构造器方式仍然可以从类的内部对类进行实例化,而静态类禁止从任何地方实例化类,其中包括从类自身内部。静态类和使用私有构造器的另一个区别在于,在使用私有构造器的类中,是允许有实例成员的,而C# 2.0和更高版本的编译器不允许静态类有任何实例成员。使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员,编译器将保证不会创建此类的实例。静态类的另一个特征在于,C#编译器会自动把它标记为sealed。这个关键字将类指定为不可扩展;换言之,不能从它派生出其他类。

更多静态类的信息可以参考这篇博客:http://blog.sina.com.cn/s/blog_48a45b950100j68w.html

参数数组

我们在某些情况下希望一个方法可以支持传递个数不限的参数(不传或传递无限多个),这时可以使用params定义一个参数数组,我们具体看下例子:

 using System;

 namespace Study
{
class Program
{
private static void Main(string[] args)
{
UseParams(, , );
UseParams2(, 'a', "test");
int[] myarray = new int[] { , , };
UseParams(myarray); Console.Read();
} public static void UseParams(params int[] list)
{
for (int i = ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
} public static void UseParams2(params object[] list)
{
for (int i = ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
}
}

当前参数数组也可以和普通参数搭配使用,但必须是最后一个参数,如下:

 using System;

 namespace Study
{
class Program
{
private static void Main(string[] args)
{
UseParams(, , , 'a', "test");
int[] myarray = new int[] { , , };
UseParams(, , myarray); Console.Read();
} public static void UseParams(int a, int b, params object[] list)
{
for (int i = ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
}
}

const和readonly

  1. readonly修饰符来表示只读域,const来表示不变常量;
  2. const只能在声明时初始化;
  3. readonly只能在声明初始化或构造器初始化时赋值,其他地方不能进行对只读域的赋值操作,否则编译器会报错;
  4. readonly可以使用static关键字描述为静态属性,const本身即为静态属性不用添加static关键字;
  5. const的类型只能为下列类型之一(或能够转换为下列类型的):sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string和enum;
  6. readonly的类型可以是C#语言的任何类型;
  7. readonly的类型如果是引用类型,则可以修改该引用类型的内部数据:
 using System;

 namespace Study
{
class Program
{
private static readonly Test test = new Test(); static void Main(string[] args)
{
test.a = ;
test.b = ; Console.WriteLine(test.a + " " + test.b); Console.Read();
}
} public class Test
{
public int a = ;
public int b = ;
}
}

结果如下:

  

类型转换

显示转换和隐式转换

 //隐式转换, 直接转换即可, 小范围数据转换大范围数据或
//子类转父类都可以使用, 这样可以安全转换
int i = ;
long l = i; //显示转换, 需要添加转换的类型, 大范围数据转换小范围数据或
//父类转子类时使用, 一般是会发生数据丢失或转换失败
double d = 11.5;
int i2 = (int)d;

is

用来判断是否是指定的类型。

as

显示转换,和(type)xxx不同的是,如果转换失败(type)xxx会进行报错,而as会返回空。

同时as只能用在引用类型和可空类型上。

方法转换

转换为字符串一般使用对象的toString()方法;

转换为int等类型可以使用Convert.ToInt32或Int32.Parse两种方法,其它类型类似;

装箱和拆箱

装箱:值类型转换为引用类型,堆栈变成记录地址,数据被存放到托管堆中,隐式转换;

拆箱:引用类型转换为值类型,数据从托管堆中放到堆栈,显示转换,可能报错;

异常处理

一般的代码在报错后就会停止运行,但写在finally中的代码在抛出异常后仍然会继续运行,所以一般finally中都会写上释放资源和内存的代码。

指定枚举的类型

默认情况下枚举的类型为int类型,但是我们也可以指定枚举类型,如下:

 enum Gender : byte
{
Female,
Male
}

静态构造函数

C#中还存在静态构造函数,即创建动态实例或者引用静态属性之前,都会调用静态构造函数。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace StudyTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(StaticConstructor.name);
Console.WriteLine(StaticConstructor.name);
Console.ReadKey();
}
} class StaticConstructor
{
private static string _name; static StaticConstructor()
{
Console.WriteLine("静态构造函数被调用了!");
_name = "StaticConstructorInstance";
} public static string name
{
get { return _name; }
}
}
}

输出如下:

 静态构造函数被调用了!
StaticConstructorInstance
StaticConstructorInstance

析构函数

当对象被GC回收时会调用析构函数,一般情况无需显示定义析构函数,但是当需要销毁非托管资源时可以显示定义析构函数进行处理。析构函数的显示定义如下:

 class Person
{
~Person()
{
Console.WriteLine("析构函数被调用了!");
}
}

使用析构函数时需要注意下面几点:

  • 不能再结构体中使用;
  • 一个类只能有一个析构函数;
  • 无法继承或重载析构函数;
  • 不能显示调用,析构函数由垃圾回收器自动调用;
  • 析构函数没有修饰符也没有参数;

索引器

当一个类需要使用类似数组的[]访问内部数据时可以使用索引器。索引器类似于属性,可使用get/set访问器,具体形式如下:

 [修饰符] 数据类型 this[索引类型 index]
{
get { //返回数据 }
set { //设置数据 }
}

下面我们看一个例子:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace StudyTest
{
class Program
{
static void Main(string[] args)
{
IndexTest it = new IndexTest();
it[] = ;
it[] = ;
it[] = ; Console.WriteLine(it[]);
Console.WriteLine(it[]);
Console.WriteLine(it[]);
Console.ReadKey();
}
} class IndexTest
{
private int[] arr = new int[]; public int this[int index]
{
get { return arr[index]; }
set { arr[index] = value; }
}
}
}

输入如下:


goto

goto用于运行代码的跳转,一般来说我们的代码都是严格的从上到下执行的,如果引入goto则会打乱这个运行顺序,造成比较难以发现的bug,那为啥C#还保留了这个功能呢,因为在某些情况下我们还是需要借助goto来方便的实现一些功能。

在Java中,我们会发现存在标签的概念,具体点击这里查看,而C#中与之对应的就是goto,比如我们在一个双重循环中希望可以直接退出整个循环,或多重循环中可以跳出到指定的某个循环,使用goto就会异常方便,示例如下:

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
for (int i = ; i < ; i++)
{
Console.WriteLine("i: " + i); for (int j = ; j < ; j++)
{
Console.WriteLine("i: " + i + ", j: " + j); if (j == )
{
if (i == )
{
//跳到指定行
goto myBreak2;
}
else
{
//跳到指定行
goto myBreak;
}
}
} //跳出小循环
myBreak:;
} //跳出大循环
myBreak2:; Console.Read();
}
}
}

运行结果如下:

 i:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:
i:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:
i:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:
i: , j:

C#学习笔记(一):一些零散但重要的知识点汇总的更多相关文章

  1. Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别)

    学习内容:存储程序与函数...这一章学的我是云里雾里的... 1.存储过程...   Mysql存储过程是从mysql 5.0开始增加的一个新功能.存储过程的优点其实有很多,不过我觉得存储过程最重要的 ...

  2. 【知了堂学习笔记】java 底层容易忽略的知识点

    1. java中的关键字 提到关键字,最主要的就是不能用关键字作为标识符,值得注意的有以下几点. ①其中goto与const在java中没有定义,但是也是关键字.这个基本用不到,但是应该有个认知. ② ...

  3. Python学习笔记第二十二周(前端知识点补充)

    目录: 一.伪类 二.样式 1.字体 2.背景图片 3.margin和padding 4.列表属性 5.float 6.clear 7.position 8.text-decoration(a标签下划 ...

  4. 【学习笔记】--- 老男孩学Python,day8 知识点补充 join,列表不能循环删除,深浅copy

    1. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 2. 列表不能再循环的时候删除. 因为索引会跟着改变 3. 字典也不能直接循环删除. 把要删除的内容记录在列表中. ...

  5. R语言学习笔记(十八):零碎知识点46-50

    seq_along与seq_len函数的使用 在for循环中有用 > seq_along(c(2,3,5)) [1] 1 2 3 > seq_len(3) [1] 1 2 3

  6. R语言学习笔记(十四):零碎知识点(41-45)

    41--ls( ) ls()可以用来列出现存的所有对象. pattern是一个具名参数,可以列出所有名称中含有字符串"s"的对象. > ls() [1] "s&qu ...

  7. R语言学习笔记(十二):零碎知识点(31-35)

    31--round(),floor()和ceiling() round()四舍五入取整 floor()向下取整 ceiling()向上取整 > round(3.5) [1] 4 > flo ...

  8. NLTK学习笔记(二):文本、语料资源和WordNet汇总

    目录 语料库基本函数表 文本语料库分类 常见语料库及其用法 载入自定义语料库 词典资源 停用词语料库 WordNet面向语义的英语字典 语义相似度 语料库基本函数表 示例 描述 fileids() 语 ...

  9. MVC学习笔记(六)---遇到的小问题汇总

    一.MVC中Controller中返回两个对象的写法如下: , msg = "成功", user = user, userInfo = person }); 二.前台向后台传入带有 ...

随机推荐

  1. 1701. Ostap and Partners(并查集-关系)

    1701 又是类似食物链的这一类题 这题是找与根节点的和差关系 因为0节点是已知的 为0  那么所有的都可以转换为与0的和差关系 可以规定合并的两节点 由大的指向小的 然后再更新和差关系 有可能最后有 ...

  2. 1350. Canteen(map)

    1350 这题没什么  就考一下map的用法吧 #include <iostream> #include<cstdio> #include<cstring> #in ...

  3. openSession()和getCureentSession()的区别

    openSession():永远是打开一个新的session getCureentSession():如果当前环境有session,则取得原来已经存在的session,如果没有,则创建一个新的sess ...

  4. WP8触摸感应Manipulation的操作

    触控感应不同事件的处理: 可将以下三个事件,绑定到一个控件中. /// <summary> /// 触摸开始事件 /// </summary> /// <param na ...

  5. Hibernate事务与并发问题处理(乐观锁与悲观锁)

    目录 一.数据库事务的定义 二.数据库事务并发可能带来的问题 三.数据库事务隔离级别 四.使用Hibernate设置数据库隔离级别 五.使用悲观锁解决事务并发问题 六.使用乐观锁解决事务并发问题 Hi ...

  6. CDN-内容推送网络

    前段时间介绍了浏览器缓存机制,通过浏览器缓存一方面可以改善用户的体验,而不用漫长地等待从服务器下载资源:另一方面减轻服务器压力.节省流量.CDN是另一种可以大幅度优化用户体验,且减轻服务器压力的技术. ...

  7. RPi 2B UART作为调试口或者普通串口

    /************************************************************************************** * RPi 2B UAR ...

  8. ☀【Grunt】插件

    Grunt Pluginshttp://gruntjs.com/plugins grunt-contrib-sass sass: { compile: { files: { 'css/core.css ...

  9. 【转】FragmentTest学习笔记1

    原文网址:http://blog.csdn.net/hishentan/article/details/20734489 源码部分: BookContent.java package com.exam ...

  10. Spring入门之HelloSpring

    Spring描述: -轻量级:Spring是非侵入式的-基于Spring开发的应用中的对象可以不依赖于Spring的API -依赖注入(DI---dependency injection,IOC) - ...