异常
C#中的异常处理与Java一模一样
using System;
using System.Threading;
using UserNamespace;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UserNamespace.Studnet;
using System.Collections;
namespace ConsoleApp1 {
class Program {
//自定义异常类,继承自Exception类,写一个自己的类即可
class ScoreException : Exception {
//如果希望自定义的异常有描述信息,只需要些一个有参构造即可
public ScoreException(string message) : base(message) { } }
static void Main(string[] args) {
int[] arry = new int[5];
/* * 1,一个try可以匹配多个catch来捕获多种异常
* 2,如果有多个catch
* 2,1、如果多个catch捕获的异常彼此之间没有继承关系,顺序无所谓
* 2,2、 如果多个catch捕获的异常彼此之间有继承关系,那么必须把父类异常放在最后 * */
try { arry[5] = 10; } catch (Exception e) {
//catch 用于捕获异常
//在C# 中所有异常都是exception的子类 Console.WriteLine(e.Message); }
finally {
//无论程序有没有异常,finally 中的代码始终会执行
Console.WriteLine("try -catch 模块结束"); }
try { ScoreException exception = new ScoreException("自定义异常");
throw exception; }
catch(ScoreException scoreException) {
Console.WriteLine(scoreException.Message);
} } }}
反射
可以通过类名、成员的名字来进行对象实例化、操作类成员,具体代码如下:
using System;
using System.Threading;
using UserNamespace;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UserNamespace.Studnet;
using System.Collections;
using System.Reflection;//反射需要用到的命名空间
namespace ConsoleApp1
{
//反射:可以通过类名、成员的名字来进行对象的实例化、操作类成员
class Person {
public int a;
private int b;
public static int c;
private static int d;
private Person() {
Console.WriteLine("Person类无参的构造方法被调用");
}
private Person(int a,double b,string c)
{
Console.WriteLine("Person类无参的构造方法被调用");
}
public void showA() { }
public void showB() { }
public static void showC() { }
public static void showD() { }
public int show(int a,int b) { return a; }
private double show(int a, double b) { return b; }
}
class Program
{
static void Main(string[] args)
{
//实例化一个Person对象
//通过类名来获取一个类型
//命名空间:如果这个类在一个命名空间中,那么在写类型名的时候需要加上
//例如:System.Int32
Type type = Type.GetType("ConsoleApp1.Person");
//实例化一个对象,默认会使用public权限的无参的构造方法来实例化
//object obj = Activator.CreateInstance(type);
//实例化一个对象,如果为true,表示可以匹配任何权限的无参构造方法
// object obj = Activator.CreateInstance(type,true);
//实例化一个对象,是通过public权限的有参的构造方法来实例化
//object obj=Activator.CreateInstance(type, 1,3.1,"hello");
//实例化一个对象,通过非public权限的有参构造方法
object obj = Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Instance , null,new object[]{1,3.1,"hello" },null);
/**
* BindingFlags:要访问的方法或字段的权限描述,必须要同时具备两个描述
* 1,要有要访问的成员的访问权限描述
* 2,要有要访问的成员的归属
* */
//通过反射访问类中的字段
//1,访问public权限的,非静态的字段a
FieldInfo fieldInfo = type.GetField("a");//给 type 对象的 a 字段进行赋值,赋值为 1
fieldInfo.SetValue(type,1);
fieldInfo.SetValue(obj, 1);//给 obj 对象的 a 字段进行赋值,赋值为 1
object objA = fieldInfo.GetValue(obj); //获取对象objA的字段 a 的值
//2, 访问private权限的,非静态的字段b
FieldInfo fieldInfoB = type.GetField("b",BindingFlags.NonPublic | BindingFlags.Instance );
fieldInfoB.SetValue(obj,3);
object objB = fieldInfoB.GetValue(obj);
//3,访问public权限的,静态的字段c
FieldInfo fieldInfoC = type.GetField("c",BindingFlags.Public | BindingFlags.Static);
fieldInfoC.SetValue(null,4);//如果要访问的是一个静态的成员,访问的主体是null
object objC = fieldInfoC.GetValue(null);
//4,访问private权限的,静态的字段d
FieldInfo fieldInfoD = type.GetField("b", BindingFlags.NonPublic | BindingFlags.Static);
fieldInfoD.SetValue(null,5);
object objD = fieldInfoD.GetValue(null);
//通过反射访问类中的方法
//1,获取没有参数的方法
MethodInfo method = type.GetMethod("showD",BindingFlags.NonPublic | BindingFlags.Static);
//方法调用,第一个参数是谁在调用方法,第二个参数是调用的方法的实参列表
method.Invoke(null,null);
//2,获取有参数有重载的方法
//Type数组中传要访问的方法的参数类型列表
MethodInfo method1 = type.GetMethod("show", BindingFlags.Public | BindingFlags.Instance,null,new Type[] {typeof(int),typeof(Double) },null);
//第二个参数是实参列表
//invoke方法的返回值,就是method1方法的返回值
object objE=method1.Invoke(obj,new object[] { 1,3.13});
Console.WriteLine(objE);
}
}
}
字符串
C#中的字符串处理基本与JAVA一致,具体基本操作代码如下:
using System;
using System.Threading;
using UserNamespace;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UserNamespace.Studnet;
using System.Collections;
using System.Reflection;//反射需要用到的命名空间
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
char[] stringArr = {'a','b','c' };
string str = new string(stringArr);
//和另外一个字符串比较
//从第0个字符开始一次比较每一个字符,知道某一个字符确定大小
int result = "hello".CompareTo("hallo");
Console.WriteLine(result);
//判断是否包含某个子串
bool c = "hello world".Contains("11");
//Endwith:判断是否以指定的字符串结尾
//startswith:判断是否以指定字符串开头
bool d = "harry.rmvb".EndsWith("rmvb");
//在一个字符串中插入一个字符串,得到一个新的字符串
string newstring = "ello".Insert(0,"h");
//Remove:删除一部分
//substring:截取一部分
string[] newstrArr="xiaoming,xiaohong,lily,lucy".Split(',');
foreach (string temp in newstrArr) {
Console.WriteLine(temp);
} }}
yield
yield return 用于多次返回(一次返回多个值)
而 return 一次只能返回一个值
yield break 多次返回值时退出
多线程
//第一种创建线程的方式
var task1 = new Task(() =>
{
for (int i = 0; i < times; i++) {
Console.WriteLine("1 "+ i);
}
});
/**
* 第二种创建线程方式
*/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)//主线程
{
int times = 5000;
var task1 = Task.Factory.StartNew(() =>
{
for (int i = 0; i < times; i++) {
Console.WriteLine("1 "+ i);
}
return "1";
});
Console.WriteLine(task1.Result);
var task2 = Task.Factory.StartNew(() =>
{
for (int i = 0; i < times; i++)
{
Console.WriteLine("2 "+i);
}
});
task1.Start();
task2.Start();
task1.Wait();
task2.Wait();
Console.Read(); } }}
异常现在线程中的捕获
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)//主线程
{
int times = 5000;
var task1 = Task.Factory.StartNew(() =>
{
throw new ApplicationException("there is an erro");
});
//使用线程中的内置方法 捕获线程中的异常
task1.ContinueWith((task)=> { Console.WriteLine(task.Exception); },
TaskContinuationOptions.OnlyOnFaulted
);
//直接在 catch包围 wait,捕获异常
try {
task1.Wait();
} catch(AggregateException aggre) {
foreach (var tem in aggre.InnerExceptions) {
Console.WriteLine(tem.Message);
}
}
Console.Read(); } }
}
并行处理
比较单线程处理任务与多线程处理任务的效率:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static void CalcTime(Action action) {
Stopwatch sw = new Stopwatch();
sw.Start();
action();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
static void Do(ref int i) {
i = (int)Math.Abs(Math.Sin(i)); }
static void Main(string[] args)//主线程
{
var list = new List<int>();
for (int i=0;i<5000000 ;i++) {
list.Add(i);
}
CalcTime(()=>list.ForEach(i=>Do(ref i)));
CalcTime(() => Parallel.ForEach(list, i => Do(ref i)));//开启部分线程进行操作
} }
}
lock关键字使操作具有原子性,使当前进行任务时不被打断,如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static int count = 0;
private static readonly object Syn = new object();
static void Increment() {
lock (Syn) {
for (int i = 0; i < 500000; i++)
{
count++;
} }
}
static void Decrement()
{
lock (Syn)
{
for (int i = 0; i < 500000; i++)
{
count--;
} }}
static void Main(string[] args)//主线程
{
var task1 = new Task(Increment);
var task2 = new Task(Decrement);
task1.Start();
task2.Start();
task1.Wait();
task2.Wait();
Console.WriteLine(count);
Console.Read();
} }
}
相同操作如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static int count = 0;
static void Increment() {
for (int i = 0; i < 500000; i++)
{
Interlocked.Increment(ref count);
}
}
static void Decrement()
{
for (int i = 0; i < 500000; i++) {
Interlocked.Decrement(ref count);
}}
static void Main(string[] args)//主线程
{
var task1 = new Task(Increment);
var task2 = new Task(Decrement);
task1.Start();
task2.Start();
task1.Wait();
task2.Wait();
Console.WriteLine(count);
Console.Read();
} }
}
其实三天并没有学完C#的基础特性,但是因为我只是为了简单的了解unity才学的C#,基本上学到这里去了解unity游戏开发就已经足够了,后面如果需要用到这些知识呢,再继续学习吧。
那就先留个笔记在这里吧:以后需要学习的时候再来学习下:
C#中迭代器模式:
https://www.bilibili.com/video/av2357992?p=13
C#中如何自定义查询运算符:
https://www.bilibili.com/video/av2357992?p=14
C#中的序列化及动态编程
https://www.bilibili.com/video/av2357992?p=16
C#中的常用工具类以及设计模式