这是「C# 学习加固」系列的第 5 篇,共 5 篇;可通过文末的系列导航继续阅读。
38. 特殊的引用类型string#
常用成员#
Length:字符串长度
IndexOf:A字符串在B字符串中第一次出现的位置
LastIndexOf:A字符串在B字符串中最后一次出现的位置
Replace:替换指定的字符
ToUpper:转为大写
ToLower:转为小写
字符串的特殊性#
首先string是引用类型,底层使用了“常量池”的技术,也就是如果存在某个字符串,则不会实例化一个新的字符串,而是复用之前的引用
string str1 = "ddd";
string str2 = "ddd";
str1 = "CCC"上面代码中str1和str2是同一个引用,但是str1修改后,str2并不会修改,这也是string的特殊性
// 这些函数都是返回一个新的字符串,不会修改原有的字符串,因为使用了常量池的技术
//Length: 字符串长度
//IndexOf:A字符串在B字符串中第一次出现的位置
//LastIndexOf:A字符串在B字符串中最后一次出现的位置
//Replace:替换字符串中指定的字符
//ToUpper:将字符串转换为大写
//ToLower:将字符串转换为小写
string name1 = "张三Abc";
string name2 = "张三Abc";
string name3 = new string("张三Abc");
// C#中允许重载运算符,如果一定要看它们的引用是否相等,要用object.ReferenceEquals
Debug.Log(name1 == name3); // 字符串的==被修改,不再是对比是否同一个引用,而是值是否相等
Debug.Log(object.ReferenceEquals(name1, name3));
Debug.Log(object.ReferenceEquals(name1, name2));39. 数组#
数组也是一种内置类型,如同字面意思,用来管理多个数据的
语法#
关键点#
- 数组本身是引用类型
- 数组中可以存放任何类型
- 数组中的数据如果没有设置值,会是该类型的默认值,引用就是null
using UnityEngine;
public class Hello : MonoBehaviour
{
void Start()
{
// 定义数组
// 定义时如果不确定值,数组内是默认值
int[] nums1 = new int[10];
int[] nums2 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 定义时就填充数据
Hero[] heros = new Hero[] {
new Hero(),new Hero(),new Hero()
};
int num;
// 修改数据,编程领域普遍情况下,计数从0开始
nums1[0] = 33;
// 获取数据
Debug.Log(nums1); // 33
// 理论上不存在删除数据的情况,但是可以让数据无效
nums1[0] = 0;
heros[0] = null; // 让数组中的数据无效
Test(nums1);
Test(nums2);
// Debug.Log(nums2[nums2.Length]); Length是数组的长度,但是索引从0开始,所以最后一个元素的索引是Length - 1
object[] objs = new object[] {1, "hello", new Hero() };
}
private void Test(int[] nums)
{
// 数组的长度,但是注意,不是有效长度,而是定义时的长度
for (int i = 0; i < nums.Length; i++)
{
var num = nums[i];
Debug.Log(num);
}
}
}
public class Hero
{
}40. 交错数组#
上节课有个特殊的地方:“数组中可以存放任何类型”,那么是否也可以将数组放数组中?
注意事项#
- 因为数组中可以放任何类型,所以也可以放数组。但是数组中的类型是确认的,所以可以产生int[][]这样的存在
- 交错数组中每个元素虽然类型一致,但是他们的元素数量可以不相同
int[] nums = new int[] {0,1,2,3,4,5,6,7,7,7 }; // 10个int
// 交错数组只是约束成员都是某个类型,但是不约束里面的内容
int[][] nums2 = new int[][] // 元素是int[]
{
new int[] {0,1,2,3,4,5,6,7,7,7 },
new int[] {0,1,2,3,4,5,6,7,7,7 },
new int[] {0,1,2,3,4,5,6,7,7,7 },
new int[] {0,1,2,3},
};
int num = nums2[0][3]; // 访问nums2[0]的第三个元素
Debug.Log(num); // 输出341. 多维数组#
多维数组是确定行列的数组
// 多维数组
int[,] nums3 = new int[2, 3] // 4行3列
{
{1,2,3},
{4,5,6},
};
Debug.Log(nums3.Length); // 输出6 多维数组元素的总长度
Debug.Log(nums3[0, 0]); // 输出1
Debug.Log(nums3[1, 0]); // 输出4
Debug.Log(nums3[0, 1]); // 输出2
for (int i = 0;i < nums3.GetLength(0);i++)
{
for (int j = 0; j < nums3.GetLength(1); j++)
{
Debug.Log(nums3[i, j]);
}
}
}42. 面向对象总结#
using UnityEngine;
public class Hello : MonoBehaviour
{
void Start()
{
Animal[] animals = new Animal[3];
animals[0] = new Dog();
animals[1] = new Cat();
animals[2] = new Fish();
for (int i = 0; i < animals.Length; i++)
{
animals[i].Eat();
}
for (int i = 0; i < animals.Length; i++)
{
// 如果动物实现了IRun接口,则调用Run方法
IRun runer = animals[i] as IRun;
if (runer != null)
{
runer.Run();
}
else
{
Debug.Log("该动物不能跑!");
}
}
}
}
public abstract class Animal
{
public abstract void Eat();
public virtual void Cry()
{
Debug.Log("");
}
}
public interface IRun
{
void Run();
}
public class Dog : Animal,IRun
{
public override void Eat()
{
Debug.Log("小狗吃东西!");
}
public void Run()
{
Debug.Log("小狗跑!");
}
}
public class Cat : Animal, IRun
{
public override void Eat()
{
Debug.Log("小猫吃东西!");
}
public void Run()
{
Debug.Log("小猫跑!");
}
}
public class Fish : Animal
{
public override void Eat()
{
Debug.Log("小鱼吃东西!");
}
}