C#语法基础
·
大部分语法与java差不多
WriteLine方法,参数($“for i={i}”)
ReadLine方法读取
ref 可以使传入函数的参数改变值(相当于C++里的&),甚至改变数据类型。
字符串常用方法
查找和比较
Contains(str):检查字符串是否包含特定的子字符串。StartsWith(str):检查字符串是否以特定的子字符串开始。EndsWith(str):检查字符串是否以特定的子字符串结束。IndexOf(str):返回指定子字符串在字符串中第一次出现的索引。LastIndexOf(str):返回指定子字符串在字符串中最后一次出现的索引。CompareTo(str):比较当前字符串与另一个字符串。
修改字符串
ToUpper():将当前字符串中的所有小写字转换成大写。ToLower():将当前字符串中的所有大写字转换成小写。Trim():从当前字符串中移除所有前导空白和后导空白。TrimStart():从当前字符串中移除所有前导空白。TrimEnd():从当前字符串中移除所有后导空白。Replace(oldStr, newStr):将当前字符串中指定的字符串替换为另一个指定的字符串。
分割和连接
Split(separator, StringSplitOptions):将字符串分割成字符串数组。Join(separator, strArray):将字符串数组连接成一个单一的字符串。
子字符串和长度
Substring(startIndex, length):提取字符串中从指定位置开始的指定数量的字符。Length:获取当前字符串中的字符数。
语法糖
-
自动属性
public class Person { public string Name { get; set; } public int Age { get; set; } } -
对象初始化
var item = new Person{name="name"}; -
集合初始化
var list = new List<int>{1,2,3}; -
匿名类型
var anonymous = new {name = "name"}; -
隐式变量声明
var item = 1; -
LINQ查询表达式
var query = from n in numbers where n > 2 select n; -
属性模式和元组模式
if(persion is {age : > 18}){ //person.Age > 18 } -
表达式主体成员
public Add(float x,float y) => x+y;
值类型变量和引用类型变量的地址对比

继承
-
public class B : A = > B类继承A类
-
protected只允许子类使用
-
voerride 是修饰在方法上的
-
struct和class默认继承object
-
Abstract:不允许实例化,接口可以不实现,等待子类实现
-
Interface:声明类型和规范,不具体实现
泛型
函数名(参数可泛型可不泛型)
类名
只要有用到泛型就必须用声明类或者方法
public class GVector<T,T2>{
//T必须是一个类类型(非值类型),并且它必须实现ILifeCycle接口
where T: class, ILifeCycle
where T2: class{
public T x;
public T2 y;
}
}
集合
list
private static void TestList()
{
var lst = new List<int>(){
3,4,5
};
PrintCollections(lst,"init list");
lst.Add(8);
lst.Insert(2,9);
lst.RemoveAt(2);
lst[2] = 15;
lst.Sort();
}
private static void PrintCollections<T>(IEnumberable<T> lst,string msg = "")
{
Console.WriteLine($"-------{msg} count = {lst.Count()}----------");
foreach (var item in lst)
{
Console.WriteLine(item.ToString + " ");
}
Console.WriteLine();
}
字典
private static void PrintCollections<T>(Dictionary<Tkey,Tval> dict,string msg = "")
{
Console.WriteLine($"-------{msg}----------");
foreach (KeyValuePair<Tkey,Tval> item in dict)
{
Console.Write($"{item.Tkey} = {item.Tval}");
}
Console.WriteLine();
}
private static void TestDictionary()
{
var dict= new Dictionary<int,string>(){
{3,"_3"},
{4,"_4"}
};
PrintCollections(dict,"init list");
dict.Add(9,"_8");
dict[9] = "_3"
dict.ContiansKey(33);
var item = dict.Remove(3);
// dict.Keys dict.Values
}
HashSet
var set = new HashSet<int>(){
1,2,3
};
set.Add(4);
set.Contains(8);
Queue
var q = new Queue<int>();
q.EnQueue(1);
q.DeQueue();
q.Count();
栈
var stack = new Stack<int>();
stack.Push(1);
var item = stack.Pop();
Console.PrintLine(stack.Count());
函数指针(将函数逻辑变量化)
//声明函数指针
public float delegate Multiplate(float val1,float val2);
//声明函数
public float Add(float val1,float val2){
return val1 + val2;
}
public float Sub(float val1,float val2){
return val1 - val2;
}
//创建指针,可以保存多个
Multiplate multiplate = Add;
muplate += Sub;
//调用
Console.PrintLine(1.2f,1.3f);
//系统默认设置的
public delegate TResult Func<in T1,in T2, out TResult>(T1 arg1,T2 arg2);//有返回值的
public delegate void Action<in T>(T obj);//无返回值的
Func<float,float,float> func = Add;
func(2.3f,1.4f);
//闭包
var val = 10;
Action closure = () => {
val += 10;
}
closure();
属性(类似注解)
//属性可以加在方法上也可以加载类上甚至加在变量上
//定义自己的Attribute
//这里的AttributeUsage属性是用于描述自定义属性的作用域和是否可以多次使用
//AttributeTargets.Class | AttributeTargets.Method = AttributeTargets.All
//AllowMultiple = true 表示可以多次使用(例如,你可以为一个方法应用多个日志记录特性)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true 表示可以多次使用(例如,你可以为一个方法应用多个日志记录特性))]
public class MyAttribute : Attribute{
public int val;
}
//使用自己的Attriution
[MyAttribute(val = 1)]
public class Program{
}
反射
用于动态获取类的信息,包括变量、函数
用于注册信息,生成代码(无聊重复的,优化,适配)
//Type类用于反射
//给Type类赋值
object val;
//获取单个class
var type = val.GetType();
//获取class集,Assembly可以获取所有的内部类、结构体、枚举、接口、函数回调,无法获取成员变量
var allType = typeof(Program).Assembly.GetTypes(){}//Program是类名
//获取类的所有信息
type.GetCustomAttributes(false);//参数表示是否要寻找特性的继承特性,也可以指定要寻找的特性,传入该特性的类就行
//因为BindingFlags是枚举类型,‘|’运算之后还是枚举类型
var methodTypes = BindingFlags.Public | BindingFlags.NonPublic | BindingFlag.Instance;
//不传参数默认所有公共方法
var funcs = type.GetMedthods(methodTypes);
foreach (var item in funcs){
item.Name;
item.GetParameters.Length();
}
//类似的还有Fields Properties
public class MyClass
{
public int MyField; // 字段
public int MyProperty { get; set; } // 属性
}
FieldInfo[] fields = type.GetFields(); // 获取字段信息
PropertyInfo[] properties = type.GetProperties(); // 获取属性信息
//创建实例
var object = Activator.CreateInstance(type);
宏
用于条件编译,比如跨平台
//必须在所有代码之上
#define TEST_MACRO_WIN
#if TEST_MACRO_WIN
#define ENABLE_LOG
#endif
using Syetem;
public class TestMacro{
public static void main(){
#if ENABLE_LOG
Conslole.WriteLine("Log...");
#else
int val = 10;
#endif
}
}
异常
可以连续判断异常
try{
object obj = null;
obj.ToString();
} catch(NullReferenceException e){
Console.WriteLine(e.ToString());
} catch(Exception e){
Console.WriteLine(e.ToString());
} finally{
Console.WriteLine();
}
//不想处理的异常就
throw new Exception("msg");
类型扩展
如果没有源码又想对该类进行扩展
public static class FloatExt{
public static int ToInt(this float val){
return (int)val;
}
}
类型转换
隐式转换(implicit conversions)和显式转换(explicit conversions)。
转换方法
以下是一些常用的转换方法:
-
隐式转换:
int i = 5; long l = i; // 隐式转换 -
显式转换:
long l = 5L; int i = (int)l; // 显式转换 -
使用
Convert类进行转换:int i = Convert.ToInt32(l); double d = Convert.ToDouble(i); -
使用
Parse方法将字符串转换为基本数据类型:int i = int.Parse("123"); double d = double.Parse("123.45"); -
使用
TryParse方法进行安全转换,它不会抛出异常:int result; bool success = int.TryParse("123", out result); -
使用
ToString方法将基本数据类型转换为字符串:string str = i.ToString();
更多推荐



所有评论(0)