C#語言基礎-03
寫這兩篇文章的目的是爲了備忘、 C#語言在大學讀書時候學過、當時做過一些東西、但是由於從事的主要工作和C#無關便忘記了。 近來公司增加了Unity業務、 寫Unity主要是C# 和js 想來C# 的語法結構和Java很相似、於是採用了C#語言作爲公司遊戲項目的主要語言。
本系列主要分上中下三篇文章來記錄。 分別牽涉到C# 中的初級、中級、高級內容。
由於本月一直忙於公司的項目、 所以發文就耽擱了, 但是回想五月忙上過去了,還是整理整理髮一篇吧。
本文主要寫一些關於C#語言的高級知識, 如果沒有看過初級的,可以先看上一篇文章,在電腦上敲敲試試,跑一下看看。
1.string相關操作
class Program {
static void Main(string[] args)
{
string s = "www.samuelnotes.com";//我們使用string類型去存儲字符串類型 字符串需要使用雙引號引起來
int length = s.Length;
if (s == "www.samuelnotes.com")
{
Console.Write("相同");
}
else
{
Console.Write("不相同");
}
Console.Write(length);
s = "http://" + s;
Console.Write(s);
char c = s[3];
Console.WriteLine(c);
for (int i = 0; i < s.Length; i++)
{
Console.WriteLine(s[i]);
}
//string s = "www.samuelnotes.com";//string 是System.String的別名
//int res = s.CompareTo("saki");//當兩個字符串相等的時候,返回0 當s在字母表中的排序靠前的時候,返回-1, 否則返回1
//Console.Write(res);
//string newStr = s.Replace('.', '-');
//string newStr = s.Replace(".", "----");//把指定的字符換成指定的字符 或者把指定的字符串換成指定的字符串
//Console.WriteLine(s);
//Console.WriteLine(newStr);
//string[] strArray = s.Split('.');
//foreach (var temp in strArray)
//{
// Console.WriteLine(temp);
//}
//string str = s.Substring(4);
//Console.WriteLine(str);
//string str = s.ToUpper();
//Console.Write(str);
//string str =s.Trim();
//Console.WriteLine(str);
int index = s.IndexOf("samuelnotesdd");//我們可以使用這個方法判斷當前字符串是否包含一個子字符串,如果不包含,返回-1,如果包含會返回第一個字符的索引
Console.WriteLine(index);
Console.ReadKey();
}
}
- stringBuilder
StringBuilder {
class Program {
static void Main(string[] args) {
//1,
//StringBuilder sb = new StringBuilder("www.samuelnotes.com");//利用構造函數創建stringbuilder
//2
//StringBuilder sb = new StringBuilder(20);//初始一個空的stringbuilder對象,佔有20個字符的大小
//3
//StringBuilder sb = new StringBuilder("www.samuelnotes.com", 100);
//sb.Append("/xxx.html");
//當我們需要對一個字符串進行頻繁的刪除添加操作的時候,使用stringbuilder的效率比較高
//Console.WriteLine(sb.ToString());
//sb.Insert(0, "http://");
//Console.WriteLine(sb);
//sb.Remove(0, 3);
//Console.WriteLine(sb);
//sb.Replace(".", "");
//sb.Replace('.', '-');
//Console.WriteLine(sb);
//string s = "www.samuelnotes.com";
//s = s + "/xxx.html";
//Console.WriteLine(s);
Console.ReadKey();
}
}
}
3.正則表達式
class Program {
static void Main(string[] args)
{
//定位元字符 ^ $
//string s = "I am blue cat.";
//string res = Regex.Replace(s, "^", "開始:");//搜索字符串 符合正則表達式的情況,然後把所有符合的位置,替換成後面的字符串
//Console.WriteLine(res);
//string res = Regex.Replace(s, "$", "結束");
//Console.WriteLine(res);
//string s = Console.ReadLine();
//bool isMatch = true;//默認標誌位,表示s是一個合法密碼(全部是數字)
//for (int i = 0; i < s.Length; i++)
//{
// if (s[i] < '0' || s[i] > '9')//當前字符如果不是數字字符
// {
// isMatch = false;
// break;
// }
//}
//if (isMatch)
//{
// Console.WriteLine("是一個合法密碼");
//}
//else
//{
// Console.WriteLine("不是一個合法密碼");
//}
//string pattern = @"^\d*$";//正則表達式
//string pattern = @"\d*";
//bool isMatch = Regex.IsMatch(s, pattern);
//Console.WriteLine(isMatch);
//string pattern = @"^\W*$";
//反義字符
//string str = "I am a cat.";
//string pattern = @"[^ahou]";//它代表一個字符, 除了ahou之外的任意一個字符
//string s = Regex.Replace(str, pattern, "*");
//Console.WriteLine(s);
//重複描述字符
//string qq1 = "234234";
//string qq2 = "234234234234234";
//string qq3 = "d4234234234";
//string pattern = @"^\d{5,12}$";
//Console.WriteLine( Regex.IsMatch(qq1,pattern) );
//Console.WriteLine( Regex.IsMatch(qq2,pattern) );
//Console.WriteLine( Regex.IsMatch(qq3,pattern) );
//string s = "34 ((*&sdflkj 路口的設計費";
//string pattern = @"\d|[a-z]";
//MatchCollection col = Regex.Matches(s, pattern);
//foreach (Match match in col)
//{
// Console.WriteLine(match.ToString());//調用tostring方法,會輸出match所匹配到的字符串
//}
//string s = "zhangsan;lisi,wangwu.zhaoliu";
////string pattern = @"[;,.]";
//string pattern = @"[;]|[,]|[.]";
//string[] resArray = Regex.Split(s, pattern);
//foreach (var s1 in resArray)
//{
// Console.WriteLine(s1);
//}
//重複 多個字符 使用(abcd){n}進行分組限定
string inputStr = Console.ReadLine();
string strGroup2 = @"(ab\w{2}){2}";// == "ab\w{2}ab\w{2}"
Console.WriteLine("分組字符重複2兩次替換爲5555,結果爲:" + Regex.Replace(inputStr, strGroup2, "5555"));
Console.ReadKey();
}
}
- 委託
我們再來看一下委託, 委託的用法很簡單,
class Program
{
private delegate string GetAString();//定義了一個委託類型,這個委託類型的名字叫做GetAString
static void Main(string[] args)
{
//int x = 40;
////string s = x.ToString();//tostring 方法用來把數據轉換成字符串
////Console.WriteLine(s);
////使用委託類型 創建實例
////GetAString a = new GetAString(x.ToString);//a指向了x中的tostring方法
//GetAString a = x.ToString;
////string s = a();//通過委託實例去調用 x中的tostring方法
//string s = a.Invoke();//通過invoke方法調用a所引用的方法
//Console.WriteLine(s);//通過委託類型是調用一個方法,跟直接調用這個方法 作用是一樣的
//實例2 使用委託類型作爲方法的參數
PrintString method = Method1;
PrintStr(method);
method = Method2;
PrintStr(method);
Console.ReadKey();
}
private delegate void PrintString();
static void PrintStr( PrintString print )
{
print();
}
static void Method1() {
Console.WriteLine("method1");
}
static void Method2() {
Console.WriteLine("method2");
}
}
打印輸出:
method1
method2
5.委託Action
Action委託 {
class Program {
static void PrintString()
{
Console.WriteLine("hello world.");
}
static void PrintInt(int i)
{
Console.WriteLine(i);
}
static void PrintString(string str)
{
Console.WriteLine(str);
}
static void PrintDoubleInt(int i1, int i2)
{
Console.WriteLine(i1+i2);
}
static void Main(string[] args)
{
//Action a = PrintString;//action是系統內置(預定義)的一個委託類型,它可以指向一個沒有返回值,沒有參數的方法
//a.Invoke();
Action<int> a = PrintInt;//定義了一個委託類型,這個類型可以指向一個沒有返回值,有一個int參數的方法
a.Invoke(12312);
//Action<string> a = PrintString;//定義了一個委託類型,這個類型可以指向一個沒有返回值,有一個string參數的方法 在這裏系統會自動尋找匹配的方法
//Action<int, int> a = PrintDoubleInt;
//a(34, 23);
Console.ReadKey();
//action可以後面通過泛型去指定action指向的方法的多個參數的類型 ,參數的類型跟action後面聲明的委託類型是對應着的
}
}
}
6.委託Func
Func委託 {
class Program {
static int Test1()
{
return 1;
}
static int Test2(string str)
{
Console.WriteLine(str);
return 100;
}
static int Test3(int i, int j)
{
return i + j;
}
static void Main(string[] args)
{
Func<int> a = Test1;//func中的泛型類型制定的是 方法的返回值類型
Console.WriteLine(a());
Func<string, int> a = Test2;//func後面可以跟很多類型,最後一個類型是返回值類型,前面的類型是參數類型,參數類型必須跟指向的方法的參數類型按照順序對應
Console.WriteLine(a("xxxx"));
Func<int, int, int> a = Test3;//func後面必須指定一個返回值類型,參數類型可以有0-16個,先寫參數類型,最後一個是返回值類型
int res = a(1, 5);
Console.WriteLine(res);
Console.ReadKey();
}
}
}
後邊再來個冒泡排序聯繫一下:
冒泡排序拓展 {
class Program {
static void Sort(int[] sortArray)
{
bool swapped = true;
do
{
swapped = false;
for (int i = 0; i < sortArray.Length - 1; i++)
{
if (sortArray[i] > sortArray[i + 1])
{
int temp = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
static void CommonSort<T>(T[] sortArray, Func<T,T,bool> compareMethod)
{
bool swapped = true;
do {
swapped = false;
for (int i = 0; i < sortArray.Length - 1; i++) {
if (compareMethod(sortArray[i],sortArray[i+1])) {
T temp = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
static void Main(string[] args) {
int[] sortArray = new int[] { 123, 23, 12, 3, 345, 43, 53, 4 };
Sort(sortArray);
foreach (var temp in sortArray)
{
Console.Write(temp + " ");
}
//Employee[] employees = new Employee[]
//{
// new Employee("dsf",12),
// new Employee("435dsf",234),
// new Employee("234dsf",14),
// new Employee("ds234f",234),
// new Employee("dssfdf",90)
//};
//CommonSort<Employee>(employees,Employee.Compare);
//foreach (Employee em in employees)
//{
// Console.WriteLine(em);
//}
Console.ReadKey();
}
}
class Employee {
public string Name { get; private set; }
public int Salary { get; private set; }
public Employee(string name, int salary)
{
this.Name = name;
this.Salary = salary;
}
//如果e1大於e2的話,返回true,否則返回false
public static bool Compare(Employee e1, Employee e2)
{
if (e1.Salary > e2.Salary) return true;
return false;
}
public override string ToString()
{
return Name + ":" + Salary;
}
}
7.多播委託
class Program {
static void Test1()
{
Console.WriteLine("test1");
//throw new Exception();
}
static void Test2()
{
Console.WriteLine("test2");
}
static void Main(string[] args) {
//多播委託
Action a = Test1;
//a = Test2;
a += Test2;//表示添加一個委託的引用
//a -= Test1;
//a -= Test2;
//if(a!=null)
// a();//當一個委託沒有指向任何方法的時候,調用的話會出現異常null
Delegate[] delegates = a.GetInvocationList();
foreach (Delegate de in delegates)
{
de.DynamicInvoke();
}
Console.ReadKey();
}
}
這樣就可以同時調用a所指向所有的方法。
8.匿名方法
namespace 匿名方法 {
class Program {
static int Test1(int arg1, int arg2)
{
return arg1 + arg2;
}
static void Main(string[] args)
{
//Func<int, int, int> plus = Test1;
//修改成匿名方法的形式
Func<int, int, int> plus = delegate(int arg1, int arg2)
{
return arg1 + arg2;
};
//匿名方法 本質上是一個方法,只是沒有名字,任何使用委託變量的地方都可以使用匿名方法賦值
Console.ReadKey();
}
}
9.lambda 表達式
namespace _09_Lambda表達式 {
class Program {
static void Main(string[] args) {
//lambda表達式用來代替匿名方法,所以一個lambda表達式也是定義了一個方法
//Func<int, int, int> plus = delegate(int arg1, int arg2) {
// return arg1 + arg2;
//};
Func<int, int, int> plus = (arg1, arg2) =>// lambda表達式的參數是不需要聲明類型的
{
return arg1 + arg2;
};
Console.WriteLine(plus(90, 60));
Func<int, int> test2 = a => a + 1;//lambda表示的參數只有一個的時候,可以不加上括號 當函數體的語句只有一句的時候,我們可以不加上大括號 也可以不加上return語句
Func<int, int> test3 = (a) =>
{
return a + 1;
};
Console.WriteLine(test2(34));
Console.WriteLine(test3(34));
Console.ReadKey();
}
}
}
- 事件
namespace 事件 {//Event
class Program
{
public delegate void MyDelegate();
//public MyDelegate mydelgate; //聲明瞭一個委託類型的變量,作爲類的成員
public event MyDelegate mydelgate;//聲明瞭一個委託類型的變量,作爲類的成員
static void Main(string[] args)
{
Program p = new Program();
p.mydelgate = Test1;
p.mydelgate();
Console.ReadKey();
}
static void Test1()
{
Console.WriteLine("test1");
}
}
}
- 觀察者設計者模式
namespace _012_觀察者設計模式_貓捉老鼠 {
class Program {
static void Main(string[] args) {
Cat cat = new Cat("加菲貓","黃色");
Mouse mouse1 = new Mouse("米奇","黑色",cat);
//cat.catCome += mouse1.RunAway;
//Mouse mouse2 = new Mouse("唐老鴨", "紅色",cat);
//cat.catCome += mouse2.RunAway;
//Mouse mouse3 = new Mouse("xx", "紅色",cat);
//cat.catCome += mouse3.RunAway;
Mouse mouse4 = new Mouse("水", "紅色",cat);
//cat.catCome += mouse4.RunAway;
//cat.CatComing(mouse1,mouse2,mouse3);//貓的狀態發生改變 在cat中調用了觀察者的方法,當觀察者發生改變的時候,需要同時修改被觀察者的代碼
cat.CatComing();
//cat.catCome();//事件不能再類的外部觸發,只能在類的內部觸發
Console.ReadKey();
}
}
}
namespace _011_觀察者設計模式_貓捉老鼠 {
/// <summary>
/// 觀察者類:老鼠
/// </summary>
class Mouse
{
private string name;
private string color;
public Mouse(string name, string color,Cat cat)
{
this.name = name;
this.color = color;
cat.catCome += this.RunAway;//把自身的逃跑方法 註冊進 貓裏面 訂閱消息
}
/// <summary>
/// 逃跑功能
/// </summary>
public void RunAway()
{
Console.WriteLine(color+"的老鼠"+name+"說: 老貓來, 趕緊跑, 我跑, 我使勁跑,我加速使勁跑 ...");
}
}
}
namespace _011_觀察者設計模式_貓捉老鼠 {
/// <summary>
/// 貓類
/// </summary>
class Cat
{
private string name;
private string color;
public Cat(string name, string color)
{
this.name = name;
this.color = color;
}
/// <summary>
/// 貓進屋(貓的狀態發生改變)(被觀察者的狀態發生改變)
/// </summary>
//public void CatComing(Mouse mouse1,Mouse mouse2,Mouse mouse3)
public void CatComing()
{
Console.WriteLine(color+"的貓"+name+"過來了,喵喵喵 ...");
//mouse1.RunAway();
//mouse2.RunAway();
//mouse3.RunAway();
if(catCome!=null)
catCome();
}
public event Action catCome;//聲明一個事件 發佈了一個消息
}
}
- 反射
namespace _012_反射和特性 {
class Program {
static void Main(string[] args) {
//每一個類對應一個type對象,這個type對象存儲了這個類 有哪些方法跟哪些數據 哪些成員
//MyClass my = new MyClass();//一個類中的數據 是存儲在對象中的, 但是type對象只存儲類的成員
//Type type = my.GetType();//通過對象獲取這個對象所屬類 的Type對象
//Console.WriteLine(type.Name);//獲取類的名字
//Console.WriteLine(type.Namespace);//獲取所在的命名空間
//Console.WriteLine(type.Assembly);
//FieldInfo[] array= type.GetFields();//只能獲取public 字段
//foreach (FieldInfo info in array)
//{
// Console.Write(info.Name+" ");
//}
//PropertyInfo[] array2 = type.GetProperties();
//foreach (PropertyInfo info in array2)
//{
// Console.Write(info.Name+" ");
//}
//MethodInfo[] array3 = type.GetMethods();
//foreach (MethodInfo info in array3)
//{
// Console.Write(info.Name+" ");
//}
//通過type對象可以獲取它對應的類的所有成員(public)
MyClass my = new MyClass();
Assembly assem = my.GetType().Assembly;//通過類的type對象獲取它所在的程序集 Assembly
Console.WriteLine(assem.FullName);
Type[] types = assem.GetTypes();
foreach (var type in types)
{
Console.WriteLine(type);
}
Console.ReadKey();
}
}
}
class MyClass
{
private int id;
private int age;
public int number;
public string Name { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public void Test1() {
}
public void Test2() {
}
}
- 特性
namespace _013_特性 {
//通過制定屬性的名字,給屬性賦值,這種事命名參數
[MyTest("簡單的特性類",ID = 100)]//當我們使用特性的時候,後面的Attribute不需要寫
class Program {
[Obsolete("這個方法過時了,使用NewMethod代替")] //obsolete特性用來表示一個方法被棄用了
static void OldMethod()
{
Console.WriteLine("Oldmethod");
}
static void NewMethod()
{
}
[Conditional("IsTest")]
static void Test1() {
Console.WriteLine("test1");
}
static void Test2() {
Console.WriteLine("test2");
}
[DebuggerStepThrough]//可以跳過debugger 的單步調試 不讓進入該方法(當我們確定這個方法沒有任何錯誤的時候,可以使用這個)
static void PrintOut(string str,[CallerFilePath] string fileName="",[CallerLineNumber] int lineNumber=0,[CallerMemberName] string methodName ="")
{
Console.WriteLine(str);
Console.WriteLine(fileName);
Console.WriteLine(lineNumber);
Console.WriteLine(methodName);
}
static void Main(string[] args) {
//NewMethod();
//OldMethod();
//Console.ReadKey();
//Test1();
//Test2();
//Test1();
//PrintOut("123");
//
Type type = typeof(Program);//通過typeof+類名也可以獲取type對象
object[] array = type.GetCustomAttributes(false);
MyTestAttribute mytest = array[0] as MyTestAttribute;
Console.WriteLine(mytest.Description);
Console.WriteLine(mytest.ID);
Console.ReadKey();
}
}
}
namespace _013_特性 {
//1, 特性類的後綴以Attribute結尾
//2, 需要繼承自System.Attribute
//3, 一般情況下聲明爲 sealed
//4, 一般情況下 特性類用來表示目標結構的一些狀態(定義一些字段或者屬性, 一般不定義方法)
[AttributeUsage(AttributeTargets.Class)]//表示該特性類可以應用到的程序結構有哪些
sealed class MyTestAttribute : System.Attribute {
public string Description { get; set; }
public string VersionNumber { get; set; }
public int ID { get; set; }
public MyTestAttribute(string des)
{
this.Description = des;
}
}
}
14.總結
還是那句話、多思考、上手敲代碼、 調試調試、多試試。 如果有問題可以評論區留言共同學習進步。