| 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#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");
//迭代器
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
){}