可空类型(Nullable)
用于对 int,double,bool 等基本变量无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是
NullAble 类型的。
在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。例如,数据库中的布尔型字段可以存储值 true 或 false,或者,该字段也可以未定义。
int a = 3;
int? b = 4;
int c;// 默认值为0
int? d;// 默认值为null
数组
二维数组
你可以声明一个 string 变量的二维数组,如下:
// 声明一个二维数组
string[,] a;
// 声明一个三维数组
int[ , , ] b;
或者声明并初始化,如下:
// 一个带有 5 行 2 列的数组
int[,] a = new int[5, 2] {
{0,0},
{1,2},
{2,4},
{3,6},
{4,8}
};
交错数组
// 声明了一个5个元素的交错数组
int[][] a = new int[5][];
交错数组看起来和二维数组有点相似,但是不同之处就是交错数组的元素里的数组长度可以不一,二维数组行列长度都是相同的
参数数组
用于传递未知个数的数组
using System;
namespace App
{
class ParmaArray
{
public int AddElements(parmas int[] arr)
{
int sum = 0;
forearch(int i in arr)
{
sum += i;
}
return sum;
}
}
class Test()
{
static void Main(string[] args)
{
ParmaArray app = new ParmaArray();
int sum = app.AddElements(10,20,30);
Console.WriteLine("sum : {0}",sum);
Console.ReadKey();
}
}
}
结构体
结构体需要注意以下几点即可
- 无法手动定义无参构造函数,无参构造函数的自动定义的
- 无法定义析构函数
- 无法继承或者被继承其他结构体
- 结构成员无法被指定为abstract,virtual和protected
- 可以使用new 创建一个结构体,也可以不用new 创建
类和结构体
首先明确,类是存储在堆空间中的,堆空间大,但访问速度较慢。结构体是储存在栈空间中的,栈空间小,但访问速度快。故而,当我们描述一个轻量级对象的时候,结构可提高效率,成本更低,所以根据需要去选择。
类
类的静态成员
当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本。就是说当你声明一个静态成员时候,不管你new多少个对象,被修改的静态成员永远都是相同一个。
上代码:
using System;
namespace StaticVarApplication
{
class StaticVar
{
public static int num;
public void count()
{
num++;
}
public int getNum()
{
return num;
}
}
class StaticTester
{
static void Main(string[] args)
{
StaticVar s1 = new StaticVar();
StaticVar s2 = new StaticVar();
s1.count();
s1.count();
s1.count();
s2.count();
s2.count();
s2.count();
Console.WriteLine("s1 的变量 num: {0}", s1.getNum());
Console.WriteLine("s2 的变量 num: {0}", s2.getNum());
Console.ReadKey();
}
}
}
// 输出结果:
// s1 的变量 num: 6
// s2 的变量 num: 6
类的静态方法
这样的函数只能访问静态变量。静态函数在对象被创建之前就已经存在。
上代码:
using System;
namespace StaticVarApplication
{
class StaticVar
{
public static int num;
public void count()
{
num++;
}
public static int getNum()
{
return num;
}
}
class StaticTester
{
static void Main(string[] args)
{
StaticVar s = new StaticVar();
s.count();
s.count();
s.count();
Console.WriteLine("变量 num: {0}", StaticVar.getNum()/* 注意看这里,并没有使用对象去调用函数,而是使用这个类名 */);
Console.ReadKey();
}
}
}
对象的传递
对象在c#中默认的是用引用传递的
这句话看上去貌似是对的,但是其实不是的,对象在方法中做为参数时同样也是值传递,只不过是复制一个内存地址过去,所有函数方法都是值传递。除非你用ref
字符串是引用类型
详解C#引用类型String
字符串是一个特殊的引用类型,它有一套字符串驻留机制
字符串一旦被创建就不会被改变,当我们修改字符串时,其实在分配新内存,这么做的好处在于当有大量的数据时,字符串不会被重复初始化,占用很多的内存空间
反射
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
例如,在unity添加了一个脚本,脚本中定义了公开的成员变量,unity面板中可以捕获到该变量,我猜想这个就是通过反射去实现的,因为反射可以反射出一个类的元素(属性,字段/成员变量,方法,构造函数),还可以执行方法,修改变量值等。待自己学习到unity那边的时候验证一下。