自己规整了一下最近写的一些关于C#的基础 , 大部分都是按照下面网站的内容学习的
网站有很多语言 ,喜欢的朋友可以保存。
https://www.runoob.com/csharp/csharp-file-io.html
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
//struct book 结构体
//{
// public string name;
// public int time;
// public float id;
// public string title;
// public string author;
// public string subject;
// public int bookid;
// public void getvalues(string t,string a,string s,int id)
// {
// title = t;
// author = a;
// subject = s;
// bookid = id;
// }
// public void DisPlay()
// {
// Debug.Log(title);
// Debug.Log(author);
// Debug.Log(subject);
// Debug.Log(bookid);
// }
//}
enum Person
{
Hight=10,
age=2
};
interface PersonInterface
{
void InterfaceTest();
}
public class CShap : MonoBehaviour
{
#region
/*简介
*
* C#是由微软开发的基于C 、C++ 的面相对象语言(oop), 面相对象的特性 : 封装、继承、多态。
* 可以看到 我们的第一段代码 是 using System.Collections; using是关键字,用于程序中包含System的命名空间,一个程序中会中多个using
* class声明,类CShap里面可以包含很多个 函数 、成员 、在 unity里面运行 大部分是 (Awake,Start、 Update等等......
*/
/*1. 成员变量
* // 1. 成员变量 在上面 Width 和 High都是成员变量 。函数 是执行指定任务的语句 void Start(){}在unity中运行后将自动执行Start里面的内容。
float Width;
float High;
void Start()
{
Width = 3;
High = 4;
float f = Width * High;
Debug.Log(f);
}
*/
/*2. 数据类型
变量分为 :值类型 、 引用类型、 指针类型
值类型:直接包含数据,比如 int float decimal 。 他们分别储存,数字、字符、浮点数 。 值类型很多具体的可以百度一下
引用类型:不包含储存数据,内置的引用类型有: Object 、Dynamic、string。
Object 是对象类型 属于终极类型,可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。
Dynamic动态类型 你可以储存任何值在动态类型,这些变量的类型检查是在运动的时候发生的。
string 字符串类型, 允许给变量分配任何字符串值
指针类型: 指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。
*/
/* 3. 类型转换
类型转换主要分为 ,普通转换和强制转换 。
普通转换 从小的整数类型转换到大的整数类型
强制转换 从大的整数类型转换到小的整数类型,强制转换会导致数据丢失
//强制转换
void Start()
{
int i = 0;
float f = 1.5f;
i = (int)f;
Debug.Log(i+"打印使会发现i=1");
}
//这是将值类型转换成string类型,打印出来的结果是10.510
void Start()
{
int i = 10;
float f = 10.5f;
string s = f.ToString() + i.ToString();
Debug.Log(s);
}
*/
/* 4. 变量
变量 分为三步: 声明变量、给变量赋值、和使用变量
每个变量都有特定的类型,类型决定了变量的内存的大小和布局
声明一个变量
int i ;
初始化一个变量
i=100;
*/
/* 5. 常量
* 常量是固定值,常量可以使任何基本数据类型,常量被赋值后不可以更改
定义常量 用关键字 const 来定义
const int i = 10;
int c = 20;
void Start()
{
int num = i + c;
Debug.Log(num);
}
*/
/* 6. 运算符
C#的运算符非别是 : 算术运算符、关系运算符、赋值运算符、逻辑运算符、位运算符、其他运算符
算术运算符: 算术 都明白就是 加减乘除 和 ++ 或者-- 我们经常用到
int num = 0;
int num2 = 0;
void Start()
{
//num2 = num + 1; //这个相信大家都知道 里面的公式就是num2=0+1 那么 num2自然等于1
//num = 10;
//num2 = num + 1;//给num赋值后 进行相加 num2=10+1 结果就是 11
num = 6;
// num2 = ++num;
num2 = num++;
//这里等于7 ,因为 在上面 num=6 , 但出现了++num ,++num代表 先递增 在赋值 相当于 num2=num+1
//但是, num++就是先赋值 后递增 ,这里换成num++ ,num已经是7了 但是他是把num=6的值赋给了num2 , 这里打印就会出现num=7,num2=6;
//相同 -- 也是这个意思 ,
Debug.Log(num);
Debug.Log(num2);
}
#region 关系运算符 :
// 关系运算符 多数是 a==b 、 a!=b、 a>b、a<b 、a<=b、a>=b
int num = 10;
int num2 = 15;
void Start()
{
if (num==num2)// 这段语句 相当于10是否等于15
{
Debug.Log(num); //如果等于了 那么打印num的值
}
else
{
Debug.Log(num2);//如果不等于打印num2的值
}
if(num!=num2)//这段呢 相当于如果10不等于15
{
Debug.Log(num);//那么打印num的值
}
else
{
Debug.Log(num2);//如果等于那么打印num2的值
}
}
//以上就是关系运算符的使用 ,大于 、小雨、大于等于 、小于等于、也是这个方法测试 我就不一一演示了
#endregion
#region 逻辑运算符
// 逻辑运算符 "&&" 多数是称为逻辑与运算符。如果两个操作数都非零,则条件为真。 "||" 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。
int i = 10;
int c = 10;
void Start()
{
if (i==10&&c==10)//这里判断 如果i等于10 并且c也等于10
{
Debug.Log("i____" + i);//那么打印的就是i____10
}
else
{
Debug.Log("c____" + c);//如果他们两个有一个不等于10就会打印c_____c
}
if(i==10||c==5)//这里判断 如果i等于10或者c等于10 ,他们其中一个满足条件 那么这个语法就成立
{
Debug.Log("c_____" + c); //i等于10了 条件满足 打印c_____10
}
else
{
Debug.Log("i_____" + i);
}
}
#endregion
#region 赋值运算符
int i;
int b;
int c;
void Start()
{
i = 6; //简单的赋值运算符,把右边操作数的值赋给左边操作数
b += i;//加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数
c -= i; //减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数
Debug.Log("i____" + i + "_____b" + b+"_______c"+c);
//赋值运算符还有 *=、/=、%=、》= 等等 ..... 其他的请百度一下
}
#endregion
#region 其他运算符
// 三元运算符
int c = 10;
int b = 20;
void Start()
{
int d = (c == 10) ? c : b; //这里的三元运算符 表示 如果 c==10了 那么 d将会得到C的值 ,如果c不等于10 那么 将得b的值
Debug.Log(d);
}
#endregion
// C# 中的运算符优先级
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级,有括号先算括号
例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。
*/
/* 7. 判断
*
* 判断结构是指定一段程序进行判断 ,为真的时候执行的语句 和 为假的时候需要执行的语句
* // if else 语句
int i = 0;
void Start()
{
if (i<10)
{
Debug.Log("如果i大于10 执行");
}
else
{
Debug.Log("如果i不大于10 执行");
}
//switch case 语句
// switch语句 允许一个变量测试多个值 ,每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。
switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量。
当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
不是每一个 case 都需要包含 break。如果 case 语句为空,则可以不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
C# 不允许从一个开关部分继续执行到下一个开关部分。如果 case 语句中有处理语句,则必须包含 break 或其他跳转语句。
一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
C# 不支持从一个 case 标签显式贯穿到另一个 case 标签。如果要使 C# 支持从一个 case 标签显式贯穿到另一个 case 标签,可以使用 goto 一个 switch-case 或 goto default。
int i = 10;
void Start()
{
switch(i)
{
case 1:
Debug.Log("如果i等于1的话执行这个语句");
break;
case 10:
Debug.Log("如果i等于10的话执行此语句");
break;
}
}
}
/* 8. 循环
* 当一段代码 需要反复执行时,可以用循环来解决这个问题
* C#循环的几种方式
* while 循环 for 循环 foreach 循环 do while 循环
//while 循环只要条件满足 就会重复执行目标语句
int c = 0;
void Start()
{
while (c < 10)
{
Debug.Log("c______" + c);
c++;
}
}
// for 循环 是一个允许您编写特定次数的循环
下面中 for循环的流程是 先执行 int i =0 分号结束, 这段代码只会执行一次 ,接下来执行i是否小于c 如果小于 执行for循环里面的语句 ,如果不小于跳出for 循环
执行完循环语句后 执行i++ , 在执行i是否小于c 小于的话 继续执行 循环语句 ,就这样 反复执行,直至到i不小于c为止
int c = 10;
void Start()
{
for (int i =0; i<c;i++)
{
Debug.Log(i);
}
}
foreach循环用于列举出集合中所有的元素,foreach语句中的表达式由关键字in隔开的两个项组成。in右边的项是集合名,in左边的项是变量名,用来存放该集合中的每个元素。
该循环的运行过程如下:每一次循环时,从集合中取出一个新的元素值。放到只读变量中去,如果括号中的整个表达式返回值为true,foreach块中的语句就能够执行。一旦集合中的元素都已经被访问到,整个表达式的值为false,控制流程就转入到foreach块后面
的执行语句。
foreach语句经常与数组一起使用,下面实例将通过foreach语句读取数组的值并进行显示。
int[] c = new int[] { 1, 5, 1 };
void Start()
{
foreach(int i in c)
{
Debug.Log(i);
}
}
*/
/* 9. 封装
封装被定义 把一句或者多个项目 封闭在一个 物理或逻辑包中,在面相对象程序中,封装是为了防止其他项目访问内容细节
C#根据使用者的要求 ,来设置使用的访问,通过访问修饰符来实现
一个访问修饰符 定义了 一个类成员的范围和可见性
public 所有对象都可以访问
private 只对该类访问
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型。
*/
/* 10. 方法
一个方法 是把 相关的语句组在一起 ,用来执行任务的语句块
要使用一个方法 你需要 定义方法 、 执行方法
一个方法的各个元素 分别是 :
访问修饰符:决定方法的可见性
返回类型:一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
方法名称:是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
参数列表:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
方法主体:方法主体,包含了完成任务所需的指令集。
public int Num(int i)
{
return i;
}
private void Start()
{
Debug.Log(Num(2));
Num2();
Num3(3);
}
public void Num2()
{
Debug.Log("执行中.....");
}
private void Num3(int c)
{
Debug.Log("执行Num3_________" + c);
}
//按引用传递惨值
// 引用参数是一个对变量内存位置的引用,他不会为变量从新创建一个位置,他直接使用原来的变量位置
void Test08(ref int i ,ref int c)
{
int num = i;
i = c;
c = num;
}
void Test08_2(int i, int c)
{
int num1 = i;
i = c;
c = num1;
}
void Start()
{
int num1 = 50;
int num2 = 100;
Test08_2(num1, num2);
Debug.Log(num1 + "___" + num2);//这里打印的结果 num1=50 ; num2=100;
Test08(ref num1, ref num2);
Debug.Log("ref 后num1___"+ num1+"___ref 后 num2____"+num2);//在这里 因为使用了关键字ref, 直接在赋值中使用了内存位置 所以num1=100;num2=50.
}
//按输出传递参数
// 可以将函数里面的值在调用的时候输出来
void Test09(out int i)
{
i = 10;
}
void Start()
{
int c;
Test09(out c);
Debug.Log(c);
}
*/
/* 11. 可空类型
?单问号 用于对 int double bool 等无法赋值为null的类型进行赋值
int? i=null;
?? 可用于判断 当为null的时候返回一个指定的值
void Start()
{
int? i=null ;
int c = i ?? 10;//如果i为null 的话 ,返回10;
Debug.Log(c);
}
*/
/* 12. 数组
数组是一个储存相同类型的元素大小顺序集合,数组是用来储存数据的集合,通常认为一个数组是用一个数据类型变量的集合
声明数组
int[] i ;
初始化数组
int[] i= new int[3];
初始化数组并给数组赋值
int[] i= new int[3]{10,5,3};
使用索引号赋值给一个单独的数组元素
int[] i=new int[3];
int[0]=10;
声明数组时 同时给数组赋值
int[] i={10,0,45,33};
//访问数据元素
int[] i = new int[3] { 50,10,11};
void Start()
{
//for 遍历数组
for (int c = 0; c < i.Length; c++)
{
Debug.Log(i[c]);
}
//foreach 遍历数组
//foreach(int c in i)
//{
// Debug.Log(c);
//}
}
//多维数据
//这是一个 三行三列的数组 三行指的是数组中括号后面大括号里面有几个 大括号 。 三列 指的是 大括号里面有几个变量
int[,] i = new int[3, 3] { { 1, 5, 2 }, { 1, 7, 2 }, { 1, 5, 7 } };
void Start()
{
foreach(int c in i)
{
Debug.Log(c);
}
}
*/
/* 13. 字符串
string 关键字来声明一个字符串变量
创建string对象
1. 通过string变量指定一个字符串值
2. 通过string类构造函数
3. 通过使用字符串 串联运算符+
4. 通过检索属性或调用一个返回字符串的方法
5. 通过格式化方法来转换一个值或对象为它的字符串表示形式
String 类中有两个 属性
1.Chars 在当前string 中获取 char指定位置
2.Length 在当前string对象中获取字符数
String 类中的方法
void Start()
{
string Myname = "mbuzhihua";
string Age = "18";
string s = null;
//比较两个字符串,并返回一个表示他们在排列顺序中相对位置的整数,该方法区分大小写,但是,如果布尔参数为真时,该方法不区分大小写。
//if (string.Compare(Myname,Age)==0)
//{
// Debug.Log("结果相等");
//}
//else
//{
// Debug.Log("结果不相等");
//}
//连接两个字符串
//string Person =string.Concat(Myname, Age);
//Debug.Log(Person);
// 判断一个字符串中是否存在的字符串值
//if (Myname.Contains("m"))
//{
// Debug.Log("字符串中有m值");
//}
//else
//{
// Debug.Log("字符串中没有m");
//}
// 创建一个与指定字符串具有相同值的新的 String 对象。
//string Scopy = string.Copy(Myname);
//Debug.Log(Scopy);
//判断字符串的结尾是否是匹配指定的字符串
//if (Myname.EndsWith(Age))
//{
// Debug.Log("判断字符串的结尾是匹配指定的字符串");
//}
//else
//{
// Debug.Log("判断字符串的结尾不是匹配指定的字符串");
//}
?????判断当前的 string 对象是否与指定的 string 对象具有相同的值。
//if (Myname.Equals("b"))
//{
// Debug.Log("有相同的字符串值");
//}
//else
//{
// Debug.Log("没有相同的字符串值");
//}
//在指定的索引后面插入一段字符串
//Debug.Log( Myname.Insert(9, "hero"));
//判断一个字符串是否为空
//if(string.IsNullOrEmpty(s))
//{
// Debug.Log("为空");
//}
//连接一个字符串数组中所有元素,用指定分隔符分割每个元素
//string[] arry = new string[] { "buzhihua", "18", "hero" };
//string jon = string.Join(",", arry);
//Debug.Log(jon);
//从指定位置 移除指定数量的字符串
// Debug.Log( Myname.Remove(0, 1));
//将字符串转换成小写返回
//string Big = "ASASAS";
//string Small = Big.ToLower();
//Debug.Log(Small);
//转换成大写返回
//string Big= Myname.ToUpper();
//Debug.Log(Big);
// 移除当前 String 对象中的所有前导空白字符和后置空白字符。
// public string Trim()
}
*/
/* 14. 结构体
* 在C#中结构体是值类型数据结构,它一个单一变量 储存各种数据类型的相关数据,struct 关键字用于创建结构体
* 定义结构体你必须要用struct 关键字来创建
* 结构体的声明和使用
* void Start()
{
book book1;
book1.name = "三国演义";
book1.time = 10;
Debug.Log(book1.name +book1.time);
}
结构体的特点
结构体可带有,方法、属性、事件、字段、运算符方法和索引
结构体不能继承其他结构和类
结构体可以实现一个或者多个借口
当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
类和结构体的不同
类是引用类型 ,结构体是值类型
结构体不能继承
结构不能声明默认的构造函数
void Start()
{
book b = new book();
b.getvalues("C Buzhihua", "bu", "ccc", 15);
b.DisPlay();
}
*/
/*枚举
* 枚举是命名一组整型常量。枚举是用enum关键字声明的
* C#枚举是值类型。枚举包含自己的值,但不能继承或传递继承
void Start()
{
int i = (int)Person.Hight;
int c = (int)Person.age;
Debug.Log("Hight" + i + "age" + c);
}
*/
/*Class类
* 当你定义一个类时,你定义了一个数据类型的蓝图,这实际上并没有定义任何数据,但他定义了类的名称意味着什么,也就是说
* 类的对象由什么组成及在这个对象上可执行什么操作。对象是类的实例。构成类的方法和变量成为类的成员
类的定义是以关键字Class,后面跟类的名称。 类的主体包含在一对花括号内。
类的函数和封装
类的成员函数是一个在类定义中有它的定义或原型函数,就像其他变量一样。
作为一个类的成员,它能在类的任何对象上操作,能访问该对象的类的所有成员
C#中的构造函数
类的构造函数是类的一个特殊函数,当创建类的新对象时执行。
构造函数的名称和类名称相同,他没有任何返回类型
C#中的析构函数
类的析构函数是类的一个特殊的成员函数,当类的对象超出执行范围执行。
析构函数的名称是在类的名字前面加一个波浪形~ 作为前缀,它不返回值,也不带任何参数。
析构函数用于程序结束之前释放资源,析构函数不能继承或重载
public CShap()
{
Debug.Log("默认构造函数");
}
~CShap()
{
Debug.Log("程序结束了");
}
//public void TestClass()
//{
// Debug.Log("1");
//}
c#类的静态成员
我们可以使用static 关键字把类的成员定义为静态的。我们生命一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本
关键字static意味着类中只有一个该成员的实例。静态变量用于定义常量,因为他们的值可以通过直接调用类而不需要创建类的实例来获取
静态变量可在成员函数或类的定义外部进行初始化,或者在类的内部初始化静态变量
public static int i = 10;
*/
/* C#继承
* 继承是面相对象程序设计中最重要的概念之一。
* 继承允许我们根据一个类来定义另一个类,这使创建和维护应用程序变得更容易。同时也利于重用代码和时间节省
* 当创建一个类的时候,程序员不需要完全重新编写新的数据成员和成员函数,只需要写一个新类,继承已有的类的成员即可,这个已有的类被称为基类,这个新类被称为派生类
*/
/*多态性
* 多态是同一个行为具有不同的展现能力。
* 多态意味着有多重形式,在面相对象编程范式中,多态往往表现为 一个接口,多个功能
* 多态性可以是静态或动态,在静态多态性中 ,往往是在编译的时候执行,动态多态性中,是函数在运动时执行
* 在C#中,每个类型都是多态的,因为包括用户类型在内的所有类型都基于Object
* 多态就是一个接口,使用不同的实例来执行不同的操作
静态多态性
在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C#提供了两种技术来实现静态多态性, 分别是
函数重载
*/
/*运算符重载
你可以重定义或重载C#中内置的运算符。程序员也可以使用用户自定义类型的运算符。
重载运算符是通过关键字 operator 后跟运算符的符号来定义
*/
/*接口
* 接口Interface
* 接口定义了所有类技能接口是应遵循的语法合同
interface PersonInterface
{
void InterfaceTest();
}
定义接口
如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。
*/
/*异常处理
* 异常处理是在程序执行期间出现的问题。C#中的异常是对程序运行时出现的特殊情况的一种响应,不如尝试除以0.
* 异常处理建立在四个关键词之上
* try 一个try块标识了一个将被激活的特定异常的代码块,后面跟catch
* catch 程序通过异常处理程序捕获异常。 catch关键字表示捕获
* finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
void Start()
{
try
{
//是否报错
}
catch (System.Exception ex)
{
//报错打印
Debug.Log(ex);
throw;
}
}
*/
#endregion
/*文件输入和输出
一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。
从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)。
void Start()
{
//读取文件
//try
//{
// using (StreamReader sr = new StreamReader("C:/Users/a/Desktop/touch.txt"))
// {
// string line;
// while((line=sr.ReadLine())!=null)
// {
// Debug.Log(line);
// }
// }
//}
//catch (System.Exception ex)
//{
// Debug.Log(ex);
//}
//写入文件并且读取
string[] s = new string[] {"你好","我是张三" };
try
{
using (StreamWriter sw = new StreamWriter("C:/Users/a/Desktop/touch.txt"))
{
for(int i=0;i<s.Length;i++)
{
sw.WriteLine(s[i]);
}
}
}
catch (System.Exception ex)
{
Debug.Log(ex);
}
try
{
using (StreamReader sr = new StreamReader("C:/Users/a/Desktop/touch.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Debug.Log(line);
}
}
}
catch (System.Exception)
{
throw;
}
}
*/
}