csharp - woodelf-treetop/rcwiki GitHub Wiki

C#语言基础

记录c#语言中值得注意的地方。

有个UWA的文章对C#语言知识结构树,做了详细总结:https://edu.uwa4d.com/course-intro/0/168

专项深入:

Unity协程

语法测试:

Queue多线程测试

alt C#与.NetFramework对照表

Unity对C#支持情况:

Unity版本 最高支持C#版本 .NetFramework版本 .Net Core版本
4.x C# 2.0 .NET Framework 2.0.NET Framework 3.0 -
5.5 C# 4.0 .NET Framework 3.5 -
2017.1 C# 6.0 .NET Framework 4.5.NET Framework 4.6 .NET Core 1.0.NET Core 1.1
2018.2 C# 7.2 .NET Framework 4.7
2018.3 C# 7.3 .NET Framework 4.8 .NET Core 2.1.NET Core 2.2
2020.2 C #8.0 - .NET Core 3.0.NET Core 3.1
C#1特性
Classes
Structs
Enums
Interfaces
Events
Operator overloading
User-defined conversion operators
Properties
Indexers
Output parameters (out and ref)
params arrays
Delegates
Expressions
using statement
goto statement
Preprocessor directives
Unsafe code and pointers
Attributes
Literals
Verbatim identifier
Unsigned integer types
//struct结构体:值类型,不能设置null,赋值时深拷贝
struct ABC{
   public string a;
   public string b;
   public ABC(string _a){
      this.a=_a;
      this.b="";
   }
}
public interface IClz{void func();}
public class Clz : IClz{
   //显示实现,用于解决接口重名:((IClz)clz).func();
   void IClz.func(){}
   public void func(){}   //隐式实现
}
public class Clz : IClz{
   //event和delegate差不多
   //但只在声明类中可操作
   //属性器用add/remove
   public event System.Action mEvent;
   public event System.Action mEvent2{
      add {mEvent+=value;}
      remove {mEvent-=value;}
   }
}
using System.Reflection;
//内置委托
public class AutoSetAttribute:System.Attribute{}
//public class AutoSet:System.Attribute{}
public class Clz{
   [AutoSet]
   public string str;
   public void test(){
      //查找类型的成员属性
      var members = typeof(Clz).GetMembers();
      var attrMems = members.Where(m => m.GetCustomAttributes(typeof(AutoSetAttribute), false).Length > 0);
      //查找集合成员属性
      var asm = Assembly.GetAssembly(typeof(Clz));
      var types = asm.GetExportedTypes();
      var attrTypes = types.Where(m=>m.GetCustomAttributes(typeof(AutoSetAttribute), false).Length>0);
   }
}
C#1.2新特性
Dispose in foreach
foreach over string specialization
C#2新特性
Generics
Partial types
Anonymous methods
Iterators, a.k.a yield statement
Nullable types
Getter/setter separate accessibility
Method group conversions (delegates)
Static classes
Delegate inference
Type and namespace aliases
Covariance and contravariance
//Generics(泛型) 泛型约束:struct值类型,class引用类型
public class Clz<T> where T:class{}

public T func<T,W>(T t = default(T))
      where T:struct
      where W:class,new
{return t;}

//静态泛型
public class Singleton<T> where T:class,new(){
   private static T t;
   public static T GetInstance(){
      if(t==null){t=new T();}
      return t;
   }
}
public class MrResource:Singleton<MrResource>{}
MrResource.GetInstance();
public class MrAudio:Singleton<MrAudio>{}
MrAudio.GetInstance();
Debug.Log(typeof(System.Action<,>));   //System.Action`3[T1,T2,T3]
//协变
public interface Child<out T>{}
public class Parent<T>:Child<T>{}
Child<object> child = new Parent<string>();
//逆变
public interface Child<in T>{}
public class Parent<T>:Child<T>{}
Child<string> child = new Parent<object>();
//Partial(不完全类型)
partial class Clz:Interface1{
   public string value1;
   public void func1(){}
}
partial class Clz:Interface2{
   public string value2;
   public void func2(){
      func1();
   }
}
//相当于
class Clz:Interface1,Interface2{
   public string value1;
   public string value2; 
}
//内置委托
public System.Action<T1,T2,T3,T4>
public System.Func<T1,T2,T3,T4,TResult>

//匿名函数
public System.Action callback = delegate(){};
//反射
using System;
using System.Reflection;

public Clz{
   public string fieldA;              //变量
   public void methodA(){};           //函数
   public string propertyB{get;set;}    //属性(函数get_propertyB,set_propertyB)
   public void func(){
      var fields = typeof(Clz).GetFields(/*..BindingFlags..*/);
      var properties = typeof(Clz).GetProperties(/*..BindingFlags..*/);
      var methods = typeof(Clz).GetMethods(/*..BindingFlags..*/);
      var members = typeof(Clz).GetMembers(/*..BindingFlags..*/);
      //映射函数
      typeof(Clz).GetMethod("methodA").Invoke(this,new object[]{});
      //映射变量
      string str = typeof(Clz).GetField("fieldA").GetValue(this);
      typeof(Clz).GetField("fieldA").SetValue(this,"");
   }
}
//assembly > namespace
//assemble: libA.DLL 或 appA.EXE
Type.GetType("Clz");               //正确
Type.GetType("Action");            //错误
Type.GetType("System.Action");     //正确
Type.GetType("UnityEngine.MonoBehaviour");     //错误
typeof(UnityEngine.GameObject).Assembly.GetType("UnityEngine.MonoBehaviour");          //正确
typeof(UnityEditor.EditorGUIUtility).Assembly.GetType("UnityEditor.EditorGUILayout");  //正确
var asm = Assembly.LoadFile("./../LibA.dll");
int?number=null;
//迭代器
IEnumerable func1(){
   yield return 1;
   yield return 2;
   yield return "a";
}
foreach(object i in func1()){} //i : [1,2,"a"]
IEnumerabler func2(){
   yield return 1;
   yield return 2;
   yield break;
   yield return "a";  //执行不到
}
var it = func2();
while(it.MoveNext()){} //it.Current : [1,"a"]

//IEnumerable > IEnumerabler
public interface IEnumerable{
   IEnumerator GetEnumerator();
}
public interface IEnumerator{
   object Current { get; }
   bool MoveNext();
   void Reset();
}
public string str{get;set;}    //自动实现属性 C# 3.0特性
public string str2{
   get{return str;}
   private set{str=value;}
}
public static class ClzExtension{
   public static string ExtMethod(this Clz self){}
}
new Clz().ExtMethod();
C#3新特性
Implicitly typed local variables
Object and collection initializers
Auto-Implemented properties
Anonymous types
Extension methods
Query expressions, a.k.a LINQ (Language Integrated Query)
Lambda expression
Expression trees
Partial methods
Lock statement
//Lambda [ˈlæmdə]表达式
System.Action act1 = ()=>Debug.Log("");
System.Action<string> act2 = s=>Debug.Log(s);
System.Action<string,string> act3 = (s1,s2)=>Debug.Log(s1+s2);
System.Action<string> act4 = (s)=>{
   Debug.Log(s);
};
System.Func<int> func1 = ()=>0;
System.Func<int> func2 = ()=>{
   return 0;
};
//LINQ [lɪŋk](Language Integrated Query)语言集成查询。
using System.Linq;

int[] names = new string[]{"a","b","c"};
//查找
IEnumerable<int> n1 = from n in names where n.Equals("a") select n;
List<string> listName = (from c in clzs where c.Age=1 select c.Name).ToList();
IEnumerable<int> n2 = names.Where(n=>n.Equals("a"));
//转换
List<int> listN = n1.ToList();
int[] arrN = n1.ToArray();
Dictionary<string,string> dic = n1.ToDictionary(n=>n);
new {name=""}.GetType(); //匿名类型
//初始化对象或集合
Clz clz = new Clz(){name="..",age=10,sex=1};
int[] arr = new int[]{0,1,2,3};
List<string> list = new List<string>{"a","b","c"};
Dictionary<string,object> dic = new Dictionary<string,object>(){
   {"name":".."},
   {"age":1},
   {"sex":1},
}
C#4.0 新特性
Dynamic binding:动态绑定
Named and optional arguments:命名参数和可选参数
Generic co- and contravariance:泛型的协变和逆变
Embedded interop types (“NoPIA”):开启嵌入类型信息,增加引用COM组件程序的中立性
string str = "";
var str2 = "";      //自动推断类型, C#3引入
var str3 = str2;    //正确,初始化时设置类型
str3 = 0;           //错误,不可以修改类型

object obj = "";
obj.Length;                //错误
dynamic obj = "";          //动态类型
obj.Length;                //正确,但是一般无代码提示
Debug.Log(obj is string);
obj = 0;                   //正确
Debug.Log(obj is int);
obj = true;                //正确
Debug.Log(obj is bool);
//命名参数,必须放到最后面
void methodA(string s1,int i2,string s3,bool b4=false){}
methodA(0,s1:"",s3:"");
string str="0";
void methodA(out string s){
   s="a";//out参数,必须在函数内进行一次赋值
}
methodA(out str);
Debug.Log(str);//str:"a"
void methodB(ref string s){
   s="b";
}
methodB(ref str);
Debug.Log(str);//str:"b"

methodA(out string str2);//C#4特性:直接声明变量
Debug.Log(str2);//str2:"a"

void methodC(ref string v1, ref string v2, ref string v3){}
string missing;
method(ref str, ref missing, ref missing);
method(ref str);//C#4特性:ref参数可选
C#5.0 新特性
Asynchronous methods 异步方法
Caller info attributes:调用时访问调用者的信息
foreach loop was changed to generates a new loop variable rather than closing over the same variable every time
//异步操作
using System.Threading;
using System.Threading.Tasks;

Task methodA(){
   return Task.Run(()=>{});
}
//async
//函数返回值:void,Task<>,IAsyncEnumerable<>,IAsyncEnumerator<>
//函数内至少调用一次 await
async Task methodB(){
   await methodA();
}
async Task<string> methodC(){
   await Task.Run(()=>{return "";});
}

void main(){
   methodB();//异步函数调用等同于普通函数,不会阻塞线程
}
using System.Runtime.CompilerServices;

//自动注入参数
//[CallerMemberName] 调用函数名
//[CallerFilePath] 调用函数全路径
//[CallerLineNumber] 调用行号
void func(
   [CallerMemberName] string callerName = "",
   [CallerFilePath] string callerFilePath = "",
   [CallerLineNumber] int callerLineNumber = 0
){}
C#6.0 新特性
Draft Specification online
Compiler-as-a-service (Roslyn)
Import of static type members into namespace:支持仅导入类中的静态成员
Exception filters:异常过滤器
Await in catch/finally blocks:支持在catch/finally语句块使用await语句
Auto property initializers:自动属性初始化
Default values for getter-only properties:设置只读属性的默认值
Expression-bodied members:支持以表达式为主体的成员方法和只读属性
Null propagator (null-conditional operator, succinct null checking):Null条件操作符
String interpolation:字符串插值,产生特定格式字符串的新方法
nameof operator:nameof操作符,返回方法、属性、变量的名称
Dictionary initializer:字典初始化
C#7.0新特性
Out variables:out变量直接声明,例如可以out in parameter
Pattern matching:模式匹配,根据对象类型或者其它属性实现方法派发
Tuple 元组
Deconstruction:元组解析
Discards:舍弃
Local Functions:本地函数
Binary Literals:二进制文字
Digit Separators:数字分隔符
Ref returns and locals:Ref返回和临时变量
Generalized async return types:异步返回类型的广泛支持
More expression-bodied members:更多表达式化的成员体
Throw expressions:抛出表达式
C#7.1新特性
Async main:异步Main方法
Default expressions:默认表达式
Reference assemblies:参考程序集
Inferred tuple element names:推断元组元素名称
Pattern-matching with generics:泛型的模式匹配
C#7.2新特性
Span and ref-like types ref-like类型的编译安全规则
In parameters and readonly references:值类型的引用语法
Ref conditional:条件ref
Non-trailing named arguments:不在尾部的指定名字参数
Private protected accessibility:访问修饰符
Digit separator after base specifier:前缀数字(非十进制)分割
C#7.3新特性
System.Enum, System.Delegate and unmanaged constraints:泛型约束,枚举、委托和非托管
Ref local re-assignment:现在可以使用ref分配运算符(= ref)重新分配 Ref locals和ref参数。
Stackalloc initializers:现在可以初始化堆栈分配的数组
Indexing movable fixed buffers:索引可移动固定缓冲区
Custom fixed statement:自定义fixed语句
Improved overload candidates:改进重载候选项
Expression variables in initializers and queries:初始化和查询中的表达式变量
Tuple comparison:元组比较
Attributes on backing fields:后备字段属性
C#8.0新特性
Nullable reference types:可空引用类型
Default interface members::默认接口成员
Recursive patterns:递归模式
Async streams:异步流
Enhanced using:增强using
Ranges and indexes:范围和索引
Null-coalescing assignment: Null合并分配
Static local functions:静态本地函数
Unmanaged generic structs:非托管泛型structs
Readonly members:只读成员
Stackalloc in nested contexts:嵌套上下文中的Stackalloc
Obsolete on property accessors:属性访问器已经过时
Permit t is null on unconstrained type parameter:不受限制的类型参数的许可
⚠️ **GitHub.com Fallback** ⚠️