C#学习记录
1.集合
1.数组
数组
优点:数组在内存中是连续储存的,所以可以快速并且容易从头到尾进行遍历元素;也可以快速的对数据进行修改
缺点:创建时要指定数组变量的大小;在两个元素之间添加元素比较麻烦
2.ArrayList
ArrayList
ArrayList的容量是ArrayList可以保存的元素量。ArrayList的初始量是0,随着元素的添加,容量会根据需要重新分配自动增加。使用整数索引可以访问这个集合的元素,索引从0开始
ArrayList的优势是可以根据使用大小动态增加,不用受到事先设置的大小的控制,可以随意的添加,插入,移除。
劣势就是在于不管什么对象都可以接受,因为在他的眼里所有的元素都是object,可以是整型,字符串…其他类型,但是在执行代码的时候是会报错的,所以他是不安全的类型。
ArrayList对于存放值类型或者结构struct的数据,用ArrayList就意味着需要将值类型装箱成object对象,使用集合元素时,还需要执行拆箱的操作,不仅麻烦,还带来了极大地性能损耗。
三、装箱与拆箱
装箱
值类型转换成引用类型
转换的步骤:
1.首先在堆内分配内存
2.接着一系列的内存拷贝动作,当前储存位置的值类型数据拷贝到堆上分配好位置
3.转换结果是对堆上新存储位置的引用
拆箱
引用类型转换成值类型
反之则为拆箱
装箱和拆箱的重要性在于装箱会影响性能和行为。
static void Main()
{
int number;
object thing;
number =12;
//boxing
thing=number;
//unboxing
number=(int)thing;
return;
}
# ref与out
```csharp
class Program
{
#region ref和out的原因
//他们可以解决在函数内部改变外部的内容,里面变了外面也要变
static void ChangeValue(int value)
{
value = 3;
}
static void ChangeArrayValue(int[] arr)
{
arr[0] = 99;
}
static void ChangeArray(int[] arr)
{
//重新声明一个数组
arr = new int[] { 10, 20, 30 };
}
#endregion
#region 知识点二 ref和out的使用
//函数参数的修饰符
//当传入的值类型参数在内部修改时或者引用类型参数在内部重新声明时
//外部的值会发生变化
//ref
static void ChangeValueRef(ref int value)
{
value = 3;
}
static void ChangeArrayRef(ref int[] arr)
{
arr = new int[] { 100, 200, 300 };
}
//out
static void ChangeValueOut(out int value)
{
value = 99;
}
static void ChangeArrayOut(out int[] arr)
{
arr = new int[] { 1000, 2000, 3000 };
}
#endregion
#region 知识点三 ref和out的区别
//ref传入的变量必须初始化 out不用
//out传入的变量必须在内部赋值 ref不用
//ref传入的变量必须初始化 但是在内部 可改可不改
//out传入的变量不用初始化 但是在内部 必须修改该值(必须赋值)
#endregion
//总结
//1.ref和out的作用:解决值类型和引用类型 在函数内部改值或者重新声明能够影响外部传入的变量 让其也被修改
//2.使用上:就是声明参数的时候前面加上ref和out关键字即可,使用时同上
//3.区别://ref传入的变量必须初始化 但是在内部 可改可不改
// out传入的变量不用初始化 但是在内部 必须修改该值(必须赋值)
static void Main(string[] args)
{
int a = 1;
ChangeValue(a);
Console.WriteLine(a);
ChangeValueRef(ref a);
Console.WriteLine(a);
ChangeValueOut(out a);
Console.WriteLine(a);
Console.WriteLine("****************");
int[] arr2 = { 1, 2, 3 };
ChangeArrayValue(arr2);
Console.WriteLine(arr2[0]);
Console.WriteLine("****************");
ChangeArray(arr2);
Console.WriteLine(arr2[0]);
ChangeArrayRef(ref arr2);
Console.WriteLine(arr2[0]);
ChangeArrayOut(out arr2);
Console.WriteLine(arr2[0]);
Console.ReadLine();
}
}
总结
ref传入的变量必须初始化 out不用
out传入的变量必须在内部赋值 ref不用
1.ref和out的作用:解决值类型和引用类型 在函数内部改值或者重新声明能够影响外部传入的变量 让其也被修改
2.使用上:就是声明参数的时候前面加上ref和out关键字即可,使用时同上
3.区别:ref传入的变量必须初始化 但是在内部 可改可不改
out传入的变量不用初始化 但是在内部 必须修改该值(必须赋值)
值类型与引用类型
值类型的存储区域在栈里面,小而快,系统会自动清理内存
枚举,结构,和除引用类型的其他都是属于值类型
值类型:在相互赋值时,把内容拷贝给对方,他变我不变
int a=10;
int b=a;
Console.WriteLine("a={0},b={1}",a,b);
//结果为a=10,b=10
b=20;
Console.WriteLine("a={0},b={1}",a,b);
//结果为a=10,b=20
引用类型的存储区域在堆里面,大而慢,需要自己手动清理内存
类,string,数组
引用类型:引用类型的赋值是让两者指向同一个值,他变我也变
int[] arr = new int[] { 1, 2, 3, 4 };
int[] arr2 = arr;
Console.WriteLine("a={0},b={1}", a, b);
Console.WriteLine("arr[0]={0},arr2[0]={1}", arr[0], arr2[0]);
arr2[0] = 5;
Console.WriteLine("修改b和arr2[0]之后");
Console.WriteLine("a={0},b={1}",a,b);
Console.WriteLine("arr[0]={0},arr2[0]={1}", arr[0], arr2[0]);
arr2 = new int[] { 99, 2, 3, 1 };
//new 相当于开了一个新的房间,和之前的没有关系,所以arr不会有变化
Console.WriteLine("arr[0]={0},arr2[0]={1}", arr[0], arr2[0]);