框架知识点(Framework+.Net+Unity+VR+AR+MR+VRunSoft)(Action+delegate+Event+EventHandle+Func+Lambda+Type)

《框架知识点(YanlzFramework)》

++框架知识点(YanlzFramework)数据库

++++框架知识点是立钻哥哥在游戏框架整理中发现的一些知识点,这个是和框架有关的。编程

++++框架知识点主要是以框架开发为核心,梳理相关知识点,为接下来的框架实战夯实基础。设计模式


++框架知识点目录:数组

++++框架知识点001Action安全

++++框架知识点002delegate委托服务器

++++框架知识点003Event事件网络

++++框架知识点004EventHandle数据结构

++++框架知识点005Func多线程

++++框架知识点006Lambda表达式框架

++++框架知识点007Type

++++框架知识点008:索引器(this[string key]





###知识点001Action

###知识点001Action

++框架知识点001Action

++++Action委托:https://msdn.microsoft.com/zh-cn/library/system.action(v=vs.110).aspx

++++Action语法:public delegate void Action()

//立钻哥哥:ActionSystem.Core/System/Action

using System;

namespace System{

    public delegate void Action();

}

++++Action委托】:封装一个方法,该方法不具备参数且不返回值。(命名空间:System)(程序集:mscorlib(位于mscorlib.dll))

++++Action委托可用于将方法做为参数传递而不用显式声明自定义委托。(封装的方法必须对应于此委托定义方法签名。这意味着,封装的方法必须具备任何参数,没有返回值。)(在C#中,该方法必须返回void。)()若要引用的方法没有参数并返回一个值,使用泛型Func<TResult>委托。)

++++当咱们使用Action委托,则不须要显示定义一个委托封装的无参数的过程。

++++delegate void Action();    //立钻哥哥:无参,无返回值

++++delegate void Action<T>(T arg1);    //有一个参数,无返回值

++++delegate void Action<T1, T2, T3, Tn>(T1 arg1, T2 arg2, T3 arg3, Tn argn)    //多个参数

++++Action委托和Func委托惟一区别就在于代理的方法(函数)有没有返回值。(有返回值选择Func委托,没有返回值选择Action委托。)

++++系统内置的两种委托(ActionFunc),绝大多数状况下能够适配任何状况,无需咱们再写大量的代码去定义委托。(根据特殊状况还需咱们手动定义委托。)

++Action示例引入(delegate显式定义=>Action=>匿名方法=>Lambda表达式)

++++立钻哥哥尝试利用四种方式来剖析引入Action概念。

 

//1、立钻哥哥:显式定义委托

using System;

 

public delegate void YanlzShowValue();    //立钻哥哥:显式定义委托

 

public class YanlzName{

    private string instanceName;

 

    public YanlzName(string name){

        this.instanceName = name;

    }

 

    public void DisplayToWindow(){

        Debug.Log(立钻哥哥:DisplayToWindow());

    }

}

 

public class YanlzTestDelegate{

    public static void Main(){

        YanlzName testName = new YanlzName(立钻哥哥);

        YanlzShowValue showMethod = testName.DisplayToWindow;

        showMethod();

    }

}

 

//2、立钻哥哥:使用Action

using System;

 

//public delegate void YanlzShowValue();    //立钻哥哥:显式定义委托

 

public class YanlzName{

}

 

public class YanlzTestDelegate{

    public static void Main(){

        YanlzName testName = new YanlzName(立钻哥哥);

        //YanlzShowValue showMethod = testName.DisplayToWindow;  //显示定义委托

        Action showMethod = testName.DisplayToWindow;    //立钻哥哥:使用Action

        showMethod();

    }

}

 

//3、立钻哥哥:使用Action委托和C#中的匿名方法

using System;

 

//public delegate void YanlzShowValue();    //立钻哥哥:显式定义委托

 

public class YanlzName{

}

 

public class YanlzAnomymous{

    public static void Main(){

        YanlzName testName = new YanlzName(立钻哥哥);

        //YanlzShowValue showMethod = testName.DisplayToWindow;  //显示定义委托

        //Action showMethod = testName.DisplayToWindow;    //立钻哥哥:使用Action

        Action showMethod = delegate(){  testName.DisplayToWindow();  }  //匿名方法

        showMethod();

    }

}

 

 

//4、立钻哥哥:使用Action委托和lambda

using System;

 

//public delegate void YanlzShowValue();    //立钻哥哥:显式定义委托

 

public class YanlzName{

}

 

public class YanlzLambdaExpression{

    public static void Main(){

        YanlzName testName = new YanlzName(立钻哥哥);

        //YanlzShowValue showMethod = testName.DisplayToWindow;  //显示定义委托

        //Action showMethod = testName.DisplayToWindow;    //立钻哥哥:使用Action

        //Action showMethod = delegate(){  testName.DisplayToWindow();  }  //匿名方法

        Action showMethod = ()=>testName.DisplayToWindow();  //使用Lambda表达式

        showMethod();

    }

}


++Action委托类型示例

++++Action是一个没有返回值,可是能够有参数的委托类型。(Action最多能够有16个参数。)

++++namesapce System{  public delegate void Action();  }

 

//立钻哥哥:利用一个简单示例增强对Action的理解

using System;

 

namespace YanlzAction{

    class YanlzMainClass{

        //立钻哥哥:无参无返回值方法

        private static void ActionTest01(){

            Debug.Log(立钻哥哥:委托一个无参无返回值方法。);

        }

 

        //立钻哥哥:参数是string,无返回值方法

        private static void ActionTest02(string str){

            Debug.Log(立钻哥哥:输出一个参数是: + str +  的方法);

        }

 

        public static void Main(string[] args){

            Action test01 = ActionTest01;    //无参数,无返回值委托类型

            test01();    //立钻哥哥:调用Action的委托实例

 

            Action<string> test02 = ActionTest02;    //参数是string,无返回值的委托

            test02(立钻哥哥);

        }

    }

}


++Action<T>委托(只有一个参数的委托)

++++Action<T>委托:https://msdn.microsoft.com/zh-cn/library/018hxwa8(v=vs.110).aspx

++++Action<T>:封装一个方法,该方法只有一个参数而且不返回值。

++++public delegate void Action<in T>( T obj)

++++使用Action<T>委托,用于封装具备单个参数的方法,就不须要显式定义委托了。

 

//1、立钻哥哥:显式定义委托

using System;

 

delegate void YanlzDisplayMessage(string message);    //立钻哥哥:显式定义委托

 

public class YanlzTestCustomDelegate{

    public static void Main(){

        YanlzDisplayMessage messageTarget;    //立钻哥哥:显式定义委托

 

        if(Environment.GetCommandLineArgs().Length > 1){

            messageTarget = ShowWindowsMessage;

        }else{

            messageTarget = Console.WriteLine;

        }

 

        messageTarget(立钻哥哥Tips: Love zuanzuan!);

    }

 

    private static void ShowWindowsMessage(string message){

        Debug.Log(message);

    }

}

 

//2、立钻哥哥:使用Action<T>

using System;

 

//delegate void YanlzDisplayMessage(string message);    //立钻哥哥:显式定义委托

 

public class YanlzTestAction01{

    public static void Main(){

        //YanlzDisplayMessage messageTarget;     //立钻哥哥:显式定义委托

        Action<string> messageTarget;    //立钻哥哥:使用Action<T>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            messageTarget = ShowWindowsMessage;

        }else{

            messageTarget = Console.WriteLine;

        }

 

        messageTarget(立钻哥哥Tips: Love zuanzuan!);

    }

 

    private static void ShowWindowsMessage(string message){

        Debug.Log(message);

    }

}

 

//3、立钻哥哥:使用Action<T>C#匿名方法。

using System;

 

//delegate void YanlzDisplayMessage(string message);    //立钻哥哥:显式定义委托

 

public class YanlzTestAnonMethod{

    public static void Main(){

        //YanlzDisplayMessage messageTarget;     //立钻哥哥:显式定义委托

        Action<string> messageTarget;    //立钻哥哥:使用Action<T>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            //messageTarget = ShowWindowsMessage;

            messageTarget = delegate(string s){  ShowWindowsMessage(s);  } //匿名方法

        }else{

            //messageTarget = Console.WriteLine;

            messageTarget = delegate(string s){  Console.WriteLine(s);  }  //匿名方法

        }

 

        messageTarget(立钻哥哥Tips: Love zuanzuan!);

    }

 

    private static void ShowWindowsMessage(string message){

        Debug.Log(message);

    }

}

 

//4、立钻哥哥:使用Action<T>lambda表达式。

using System;

 

//delegate void YanlzDisplayMessage(string message);    //立钻哥哥:显式定义委托

 

public class YanlzTestAnonMethod{

    public static void Main(){

        //YanlzDisplayMessage messageTarget;     //立钻哥哥:显式定义委托

        Action<string> messageTarget;    //立钻哥哥:使用Action<T>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            //messageTarget = ShowWindowsMessage;

            //messageTarget = delegate(string s){ ShowWindowsMessage(s); } //匿名方法

            messageTarget = s => ShowWindowMessage(s);   //lambda表达式

        }else{

            //messageTarget = Console.WriteLine;

            //messageTarget = delegate(string s){  Console.WriteLine(s);  }  //匿名方法

            messageTarget = s => Console.WriteLine(s);  //lambda表达式

        }

 

        messageTarget(立钻哥哥Tips: Love zuanzuan!);

    }

 

    private static void ShowWindowsMessage(string message){

        Debug.Log(message);

    }

}


++拓展:List<T>.ForEach方法

++++ForEachForEach<T>方法都采用Action<T>委托做为一个参数。(因为委托封装的方法,可对数组或列表中每一个元素执行操做。)

++++示例:利用Action<T>要打印的内容委托List<T>对象。

//立钻哥哥:在此示例中,Print方法用于向控制台显示列表的内容。(注意:该示例不显式声明Action<T>变量。相反,它将引用传递到的方法,它采用单个参数,而且它们将返回到的值不返回List<T>.ForEach方法,其单个参数是Action<T>委托。)(在示例中,Action<T>委托不显式实例化)

using System;

 

class YanlzProgram{

    static void Main(){

        List<string> names = new List<string>();

        names.Add(Yanlz);

        names.Add(zuanzuan);

        names.Add(wangjue);

        names.Add(xiaojue);

 

        names.ForEach(YanlzPrint);    //立钻哥哥:using the YanlzPrint method

 

        //立钻哥哥:demonstrate the anonymous method

        names.ForEach(delegate(string name){

            Console.WriteLine(name);

        });

    }

 

    private static void YanlzPrint(string s){

        Console.WriteLine(s);

    }

}


++Action<T1, T2>委托

++++Action<T1, T2>:封装一个方法,该方法具备两个参数且不返回值。(若要引用的方法,具备两个参数并返回一个值,使用泛型Func<T1, T2, TResult>委托。)

++++public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2)

 

//1、立钻哥哥:显式声明委托

using System;

 

delegate void YanlzConcatStrings(string string1, string string2);  //立钻哥哥:显式声明委托

 

public class YanlzTestDelegate{

    public static void Main(){

        string message1 = 立钻哥哥:The first line of a message.;

        string message2 = 立钻哥哥:The second line of a message.;

        YanlzConcatStrings myConcat;    //立钻哥哥:显式声明委托

 

        if(Environment.GetCommandLineArgs().Length > 1){

            myConcat = MyWriteToFile;

        }else{

            myConcat = MyWriteToConsole;

        }

 

        myConcat(message1, message2);

    }

 

    private static void MyWriteToConsole(string string1, string string2){

        Console.WriteLine(立钻哥哥:{0}\n{1}, string1, string2);

    }

 

    private static void MyWriteToFile(string string1, string string2){

        StreamWriter writer = null;

        try{

            writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false);

            writer.WriteLine(立钻哥哥:{0}\n{1}, string1, string2);

        }catch{

            Console.WriteLine(立钻哥哥:File write operation failed...);

        }finally{

            if(writer != null){

                writer.Close();

            }

        }

    }

}

 

//2、立钻哥哥:使用Action<T1, T2>

using System;

 

//delegate void YanlzConcatStrings(string string1, string string2);  //立钻哥哥:显式声明委托

 

public class YanlzTestDelegate{

    public static void Main(){

        string message1 = 立钻哥哥:The first line of a message.;

        string message2 = 立钻哥哥:The second line of a message.;

        //YanlzConcatStrings myConcat;   //立钻哥哥:显式声明委托

        Action<string, string> myConcat;    //立钻哥哥:使用Action<T1, T2>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            myConcat = MyWriteToFile;

        }else{

            myConcat = MyWriteToConsole;

        }

 

        myConcat(message1, message2);

    }

}

 

//3、立钻哥哥:使用Action<T1, T2>和匿名方法

using System;

 

//delegate void YanlzConcatStrings(string string1, string string2);  //立钻哥哥:显式声明委托

 

public class YanlzTestDelegate{

    public static void Main(){

        string message1 = 立钻哥哥:The first line of a message.;

        string message2 = 立钻哥哥:The second line of a message.;

        //YanlzConcatStrings myConcat;   //立钻哥哥:显式声明委托

        Action<string, string> myConcat;    //立钻哥哥:使用Action<T1, T2>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            //myConcat = MyWriteToFile;

            myConcat = delegate(string s1, string s2){ MyWriteToFile(s1, s2); }  //匿名函数

        }else{

        //myConcat = MyWriteToConsole;

        myConcat = delegate(string s1, string s2){ MyWriteToConsole(s1, s2); };  //匿名

    }

 

    myConcat(message1, message2);

    }

}

 

//4、立钻哥哥:使用Action<T1, T2>Lambda表达式

using System;

 

//delegate void YanlzConcatStrings(string string1, string string2);  //立钻哥哥:显式声明委托

 

public class YanlzTestDelegate{

    public static void Main(){

        string message1 = 立钻哥哥:The first line of a message.;

        string message2 = 立钻哥哥:The second line of a message.;

        //YanlzConcatStrings myConcat;   //立钻哥哥:显式声明委托

        Action<string, string> myConcat;    //立钻哥哥:使用Action<T1, T2>

 

        if(Environment.GetCommandLineArgs().Length > 1){

            //myConcat = MyWriteToFile;

            //myConcat = delegate(string s1, string s2){ MyWriteToFile(s1, s2); } //匿名函数

            myConcat = (s1, s2)=>MyWriteToFile(s1, s2);    //立钻哥哥:Lambda表达式

 

        }else{

            //myConcat = MyWriteToConsole;

            //myConcat = delegate(string s1, string s2){ MyWriteToConsole(s1, s2); }; //匿名

            myConcate = (s1, s2)=>MyWriteToConsole(s1, s2);  //Lambda表达式

        }

 

        myConcat(message1, message2);

    }

}


++示例:Action实际应用参考

//立钻哥哥:咱们经过这个简单示例,熟悉一下Action及相关应用场景。

using System;

 

public class YanlzDemoAction{

    public Action action;

    public Action<int> action1;

    public Action<int, string> action2;

    public Action<List<int>> action3;

 

    //立钻哥哥:不带参数

    public void ActionDemo(){

        if(null != action){

            action();

        }

    }

 

    //立钻哥哥:带一个参数

    public void ActionDemo(int a){

        if(action1 != null){

            action1(a);

        }

    }

 

    //立钻哥哥:带两个参数

    public void ActionDemo(int a, string str){

        if(action2 != null){

            action2(a, str);

        }

    }

 

    //立钻哥哥:带一个列表

    public void ActionDemo(List<int> list){

        if(action3 != null){

            action3(list);

        }

    }

}    //立钻哥哥:public class YanlzDemoAction

 

public class MyCSharpDemo : MonoBehaviour{

    Action action;

 

    //Use this for initialization

    void Start(){

        YanlzDemoAction demo = new YanlzDemoAction();

        demo.action = TestAction;

        demo.action1 = TestAction;

        demo.action2 = TestAction;

        demo.action3 = TestAction;

 

        List<int> list = new List<int>(){  10,  20,  30,  40  };

        demo.ActionDemo();

        demo.ActionDemo(20);

        demo.ActionDemo(20, 立钻哥哥);

        demo.ActionDemo(list);

    }

 

    //Update is called once per frame

    void Update(){

    }

 

    //立钻哥哥:不带参数

    void TestAction(){

        Debug.Log(立钻哥哥:不带参数);

    }

 

    //立钻哥哥:带一个参数

    void TestAction(int a){

        Debug.Log(立钻哥哥:带一个参数 =  + a);

    }

 

    //立钻哥哥:带2个参数

    void TestAction(int a, string str){

        Debug.Log(立钻哥哥:带2个参数 a  + a +  str=  + str);

    }

 

    //立钻哥哥:带一个列表

    void TestAction(List<int> list){

        Debug.Log(立钻哥哥:带一个列表);

        for(int i = 0;  i < list.Count;  i++){

            Debug.Log(立钻哥哥:i= + list[i]);

        }

    }

 

}    //立钻哥哥:public class MyCSharpDemo : MonoBehaviour{}


++拓展:委托、事件、匿名方法、Action

++++立钻哥哥:咱们经过此小节,来熟悉一下:委托、事件、匿名方法、Action等的相关知识点。

++++委托和事件的命名:

--委托以EventHandler做为后缀命名,例如:SalesOutEventHandler

--事件以其对应的委托类型,去掉EventHandler后缀,并加上On前缀构成。

--例如:对于StateChangeEventHandler委托类型的事件,其事件名称为:OnStateChange

public delegate void StateChangeEventHandler();

public class YanlzProduct{

    public StateChangeEventHandler OnStateChange;

}

 

++++【事件Event】:实现相似观察者设计模式,一对多的通知。(至关于C++的函数指针的一个列表。)

//立钻哥哥:Event事件在UI上的事件回调用途很常见:

public class YanlzEventManager : MonoBehaviour{

    public delegate void MyClickAction();

    public static event MyClickAction OnClicked;

 

    void OnGUI(){

        if(GUI.Button(new Rect(Screen.width/2-50, 5, 100, 30), Click)){

            if(OnClicked != null){

                OnClicked();

            }

        }

    }

 

}    //立钻哥哥:public class YanlzEventManager : MonoBehaviour{}

 

//立钻哥哥:收到点击事件随机改变颜色

public class YanlzTurnColorScript : MonoBehaviour{

    void OnEnable(){

        YanlzEventManager.OnClicked += MyTurnColor;

    }

 

    void OnDisable(){

        YanlzEventManager.OnClicked -= MyTurnColor;

    }

 

    void MyTurnColor(){

        Color col = new Color(Random.value, Random.value, Random.value);

        renderer.material.color = col;

    }

}    //立钻哥哥:public class YanlzTurnColorScript : MonoBehaviour{}

 

++++事件和委托的区别:

--event后只能用“+=-=”来添加或移除处理,使用“=”赋值会报错。(在必定程度上保证了event系统在一个事件触发后感兴趣的系统都会获得通知,而不会被一个错误的赋值把注册的处理都覆盖掉。)

--事件是一种特殊的委托的实例,或者说是受限制的委托,是委托的一种特殊应用,在类的外部只能施加+=-=操做符,两者本质上是一个东西。

--事件只容许用add(+=)remove(-=)方法来操做,这致使了它不容许在类的外部被直接触发,只能在类的内部适合的时机触发。(委托能够在外部被触发,可是别这么用。)(使用中,委托经常使用来表达回调,事件表达外发的接口。)

--事件不能够看成形参传递,可是委托能够。

--委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具备彻底相同的行为。

--委托方法的使用能够像其余任何方法同样,具备参数和返回值。

--委托能够看做是对函数的抽象,是函数的“类”,委托的实例将表明一个具体的函数。

--一个委托能够搭载多个方法,全部方法被依次唤起,更重要的是,它可使委托对象搭载的方法不须要属于同一类。

--委托是一个类,它定义了方法的类型,使得能够将方法当作另外一个方法的参数来进行传递,这种将方法动态地赋给参数的作法,能够避免在程序中大量使用IF-ELSESwitch)语句,同时使得程序具备更好的可扩展性。

--使用委托能够将多个方法绑定到同一个委托变量,当调用此变量时,能够依次调用全部绑定的方法。

--Event事件封装了委托类型的变量,使得:在类的内部,无论声明它是public仍是protected,它老是private的。

 

++++匿名函数:

//立钻哥哥:使用匿名方法能够不用把外部变量(好比类成员)用参数传给专门的方法(事件处理),能够直接使用这些变量。

static void YanlzHandleDemoEvent(object sender, EventArgs e){

    Debug.Log(立钻哥哥:Handled by YanlzHandleDemoEvent);

}

 

//1、立钻哥哥:为这个方法建立一个委托实例

EventHandle handler;

handler = new EventHandler(YanlzHandleDemoEvent);   //handler = YanlzHandleDemoEvent;

handler(null, EventArgs.Empty);

 

//2、立钻哥哥:匿名方法,直接写回调方法的实现

string str = 立钻哥哥:Handled anonymously;

handle = delegate(object sender, EventArgs e){

    Debug.Log(str);    //外部变量

    Debug.Log(立钻哥哥:Handled by YanlzHandleDemoEvent);

};

handler(null, EventArgs.Empty);

 

++++Action:和delegate差很少的功能:

//立钻哥哥:模拟网络模块的类,收到消息后走回调。

public class YanlzNetworkManager{

    Queue<Action<string>> Callbacks;

 

    public YanlzNetworkManager(){

        Callbacks = new Queue<Action<string>>();

    }

 

    public void SendMessage(Action<string> callback){

        Callbacks.Enqueue(callbak);

    }

 

    public void Run(){

        string getData = 立钻哥哥:这是从网络获得的消息;

    

        Action<string> callback = Callbacks.Dequeue();

        Callback(getData);

    }

}    //立钻哥哥:public class YanlzNetworkManager{}

 

class YanlzProgram{

    static void Main(string[] args){

        YanlzNetworkManager networkMgr = new YanlzNetworkManager();

 

        networkMgr.SendMessage((string data)=>{

            MyCallback(data);

        });

        networkMgr.Run();

    }

 

    static void MyCallback(string data){

        Debug.Log(立钻哥哥:data= + data);

    }

 

}    //立钻哥哥:class YanlzProgram{}





###知识点002delegate委托

###知识点002delegate委托

++框架知识点002delegate委托

++++delegate关键字在编译器生成代码时会映射到调用DelegateMulticastDelegate类的成员的方法调用。(可使用定义方法签名的语法来定义委托类型,只需在添加delegate关键字便可。)

++++Delegate类:表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。(public abstract class Delegate : ICloneable, ISerializable{}

++++委托语法:关键字delegate + 返回值 + 委托名 + 参数

++++public delegate int LovezuanzuanHandler<in T>(T left, T right);

++++delegate(委托)是表示将方法做为参数传递给其余方法。(委托相似于函数指针,但与函数指针不一样的是,委托是面向对象的,类型安全的和保险的。)

++++委托(delegate)能够当作是一种数据类型,它能够定义变量。(不过是一种特殊的变量:委托定义的变量,能够接受的数值是一个或多个函数方法,能够理解成它是存放函数方法的变量,或理解成委托就是一个函数方法指针。)(将委托和函数方法关联起来,除了在建立对象的时候关联方法也能够经过“+=”绑定方法,也能够经过“-=”解绑来实现函数方法的关联。)

++++委托既能引用静态方法,也能引用实例方法。(基于委托开发事件驱动程序变得简单)(使用委托能够大大简化多线程编程的难度。)

++++委托是一个类,它定义了方法的类型,使得能够将方法当作另外一个方法的参数来进行传递,这种将方法动态地赋给参数的作法,能够避免在程序中大量使用IF-ELSE(Switch)语句,同时使得程序具备更好的可扩展性。(使用委托能够将多个方法绑定到同一个委托变量,当调用此变量时,能够依次调用全部绑定的方法。)(委托在编译的时候确实会编译成类,delegate是一个类,因此在任何能够声明类的地方均可以声明委托。)

++++C#使用委托将方法做为参数给另外一个方法,委托将方法做为对象封装起来,容许在运行时间接地绑定一个方法调用。(在CC++中利用函数指针)

++++C#中内置了三种委托方式:Action委托、Func委托、Predicate委托等。


++立钻哥哥带您理解:C#委托

++++立钻哥哥:委托是C#编程一个很是重要的概念,也是一个难点。

++++委托的理解:

--从数据结构来说,委托和类同样是一种用户自定义类型。

--从设计模式来说,委托(类)提供了方法(对象)的抽象。

++++委托是方法的抽象,它存储的就是一系列具备相同签名和返回类型的方法的地址。(调用委托的时候,委托包含的全部方法将被执行。)

++++委托是类型,与类同样,委托变量必须在被用来建立变量以及类型对象以前声明:

--delegate void YanlzDelegate(int x);   //立钻哥哥:delegate是委托的关键字

--YanlzDelegate del1, del2, del3;    //声明委托变量

--del1 = new YanlzDelegate(myClass1.MyFunc1);    //del1 = myClass1.MyFunc1;

--del2 = new YanlzDelegate(myClass2.MyFunc2);    //del2 = myClass2.MyFunc2;

--del3 = del1 + del2;    //立钻哥哥:组合调用列表

--del3();    //委托调用(调用空委托会抛异常)

++++委托中匿名方法的使用:delegate(参数){  语句块  }

--delegate int MyYanlzDelegate(int x);    //立钻哥哥:定义一个委托

--MyYanlzDelegate del = delegate(int x){  return x;  }  //匿名方法不会显式声明返回值

++++Lambda表达式:主要用来简化匿名方法的语法。(编译器已知道将方法赋值给委托,就能够删除delegate关键字了)

    --Lambda运算符:“=>”:读做“goes to

--delegate int YanlzDelegate(int x);    //立钻哥哥:定义一个委托

--YanlzDelegate del1 = delegate(int x){  return x;  }    //匿名方法

--YanlzDelegate del2 = (int x)=>{  return x;  }    //Lambda表达式

--YanlzDelegate del3 = x => {  return x;  }    //简写的Lambda表达式


++示例:C#委托应用举例

//立钻哥哥:经过一个简单的示例,加深理解delegate委托

using System;

 

namespace YanlzUsingDelegate{

    class MyStudent{

        private string name;    //立钻哥哥:姓名

        private double score;    //成绩

    

        //立钻哥哥:构造函数,初始化学生姓名和成绩

        public MyStudent(string name, double score){

            this.name = name;

            this.score = score;

        }

 

        //立钻哥哥:求最大值(静态方法)

        public static object YanlzFuncMax(object obj1, object obj2){

            MyStudent st1 = (MyStudent)obj1;

            MyStudent st2 = (MyStudent)obj2;

 

            return st1.score > st2.score ? st1 : st2;

        }

 

        //立钻哥哥:求最小值(静态方法)

        public static object YanlzFuncMin(object obj1, object obj2){

            MyStudent st1 = (MyStudent)obj1;

            MyStudent st2 = (MyStudent)obj2;

 

           return st1.score < st2.score ? st1 : st2;

        }

 

    }    //立钻哥哥:class MyStudent{}

 

    class YanlzProgram{

        delegate object YanlzDelegate(object o1, object o2);

 

        //立钻哥哥:以委托做为参数定义方法,求最大值和最小值

        static MyStudent YanlzFunc(MyStudent st1, MyStudent st2, YanlzDelegate myFunc){

            return (MyStudent)myFunc(st1, st2);

        }

 

        static void Main(string[] args){

            MyStudent[] stus = {

                new MyStudent(Yanlz, 80),

                new MyStudent(zuanzuan, 90),

                new MyStudent(wangjue, 100),

                new MyStudent(xiaojue, 95)

            };    //立钻哥哥:建立学生数组

 

            //立钻哥哥:建立委托对象,关联静态方法

            YanlzDelegate delegateMax = new YanlzDelegate(MyStudent.YanlzFuncMax);

            YanlzDelegate delegateMin = new YanlzDelegate(MyStudent.YanlzFuncMin);

 

            MyStudent maxStu, minStu;

            maxStu = minStu = stus[0];

 

            //立钻哥哥:利用YanlzFunc()方法求最大值和最小值

            for(int i = 1;  i < stus.Length - 1;  i++){

                maxStu = YanlzFunc(maxStu, stus[i], delegateMax);

                minStu = YanlzFunc(minStu, stus[i], delegateMin);

            }

 

            Debug.Log(立钻哥哥:最大值{0},最小值{1}, maxStu, minStu);

        }

 

    }    //立钻哥哥:class YanlzProgram{}

 

}    //立钻哥哥:namespace YanlzUsingDelegate{}

 

++++立钻哥哥:该程序中,方法的回调体如今YanlzFucn()方法中,它包含一个YanlzDelegate类型的参数myFunc,经过该参数,能够将MyStudent.YanlzFuncMax()方法传递到YanlzFunc()方法中求最大值,将MyStudent.YanlzFuncMin()方法传递到YanlzFunc()方法中秋最小值。


++立钻哥哥带您拓展delegate委托

++++public delegate void GreetingDelegate(string name);    //立钻哥哥:声明委托

++++public void GreetingPeople(string name, GreetingDelegate method){}    //委托做参数

++++实际上,委托在编译的时候确实会编译成类,delegate是一个类,因此在任何能够声明类的地方均可以声明委托

++++委托是一个类,它定义了方法的类型,使得能够将方法看成另外一个方法的参数来进行传递,这种将方法动态地赋给参数的作法,能够避免在程序中大量使用IF-ElseSwitch)语句,同时使得程序具备更好的可扩展性。

++++利用委托实现一个简单功能:

//立钻哥哥:method的类型就是委托,method参数可以肯定方法的种类,method表明方法的参数类型和返回类型。

class YanlzHelloWorld{

    public delegate void YanlzGreetingDelegate(string name);

 

    public static void EnglishGreeting(string name){

        Debug.Log(立钻哥哥:hello,  + name);

    }

 

    public static void ChineseGreeting(string name){

        Debug.Log(立钻哥哥:你好,  + name);

    }

 

    public void YanlzGreetingPeople(string name, YanlzGreetingDelegate myMethod){

        myMethod(name);

    }

}

 

//1、立钻哥哥:简单测试

class YanlzProgram01{

    static void Main(string[] args){

        YanlzHelloWorld myHelllo = new YanlzHelloWorld();

        myHello.YanlzGreetingPeople(立钻哥哥, YanlzHelloWorld.ChineseGreeting);

    }

}

 

//2、立钻哥哥:声明委托变量

class YanlzProgram02{

    static void Main(string[] args){

        YanlzHelloWorld myHello = new YanlzHelloWorld();

        YanlzHelloWorld.YanlzDelegate delegate1, delegate2;

        delegate1 = YanlzHelloWorld.EnglishGreeting;

        delegate2 = YanlzHelloWorld.ChineseGreeting;

    

        myHello.YanlzGreetingPeople(yanlz, delegate1);

        myHello.YanlzGreetingPeople(立钻哥哥, delegate2);

    }

}

 

//3、立钻哥哥:委托能够将多个方法赋给同一个委托,或者叫将多个方法绑定到同一个委托,当调用这个委托的时候,将依次调用其所绑定的方法:

YanlzHelloWorld.YanlzGreetingDelegate myDelegate;

myDelegate = YanlzHelloWorld.EnglishGreeting;

myDelegate += YanlzHelloWorld.ChineseGreeting;

 

YanlzHelloWorld myHello = new YanlzHelloWorld();

myHello.YanlzGreetingPeople(立钻你哥哥, myDelegate);

 

//4、立钻哥哥:尝试经过委托直接调用EnglishGreetingChineseGreeting

YanlzHelloWorld.YanlzGreetingDelegate myDelegate;

myDelegate = YanlzHelloWorld.EnglishGreeting;

myDelegate(立钻哥哥);

 

//5、立钻哥哥:多播委托,第一次用的是“=”,是赋值的语法;第二次,用的是“+=”,是绑定的语法。(若是第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误)(可使用“-=”取消对方法的绑定。)

YanlzHelloWorld.YanlzGreetingDelegate myDelegate = new YanlzHelloWorld.YanlzGreetingDelegate(YanlzHelloWorld.ChineseGreeting);

myDelegate += YanlzHelloWorld.EnglishGreeting;

myDelegate(立钻哥哥);

 

myDelegate -= YanlzHelloWorld.ChineseGreeting;

myDelegate(立钻哥哥);

 

++++匿名函数:

//立钻哥哥:利用委托实现一个按钮的点击事件

public delegate void YanlzClickHandler();

 

//1、立钻哥哥:普通的委托调用(赋值对应的方法或直接new关联一个方法)

class MyButton{

    public static void MyClickFinished(){

        Debug.Log(立钻哥哥:按钮被点击了!);

    }

}

 

YanlzClickHandler myDelegate;

myDelegate = MyButton.MyClickFinished;

myDelegate();

 

//2、立钻哥哥:利用匿名函数(在初始化时内敛声明的方法,使得委托的语法更简洁)

YanlzClickHandler myClick = delegate(){

    Debug.Log(立钻哥哥:匿名函数:按钮被点击了);

}

myClick();

 

++++C#中内置了三种委托形式:Func委托、Action委托、Predicate委托。

--Func委托的类型(有返回值的函数:TResult:返回类型):

    ----delegate TResult Func<TResult>();

    ----delegate TResult Func<T1, TResult>(T1 arg1);

    ----delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);

    ----delegate TResult Func<T1, T2, T3, Tn, TResult>(T1 arg1, T2 arg2, T3 arg3, Tn argn);

    ----示例:使用Func委托函数带有返回值,即TResult

    //1、立钻哥哥:没有参数(delegate TResult Func<TResult>

    Func<string> myFunc01 = delegate(){

        return 立钻哥哥:我是Func<TResult>委托出来的结果。;

    };

    string myResultStr01 = myFunc01();

    Debug.Log(立钻哥哥:result:  + myResultStr01);

 

    //2、立钻哥哥:有1个参数(delegate TResult Func<T1, TResult>(T1 arg1)

    Func<string, string> myFunc02 = delegate(string s){

        return s.ToLower();

    };

    string myResultStr02 = myFunc02(YANLIZUAN);

    Debug.Log(立钻你哥哥:result: + myResultStr02);

 

    //3、立钻哥哥:有2个参数(delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2)

    Func<string, string, string> myFunc03 = delegate(string str1, string str2){

        return str1 +   + str2;

    };

    Debug.Log(立钻哥哥:result: + myFunc03(立钻哥哥, Func<T1,T2,TResult>));

--Action委托:

    ----delegate void Action();

    ----delegate void Action<T>(T arg);

    ----delegate void Action<T1, T2>(T1 arg1, T2 arg2);

    ----delegate void Action<T1, T2, T3, Tn>(T1 arg1, T2 arg2, T3 arg3, Tn argn);

--Func委托和Action委托的惟一区别:在于代理的方法(函数)有么有返回值。

    ----有返回值选择Func委托。(delegate TResult Func<TResult>()

----没有返回值选择Action委托。(delegate void Action()

    --系统内置的Func委托和Action委托绝大多数状况下能够适配任何状况,无需咱们再写大量的代码去定义委托。(根据特殊状况还需咱们手动定义委托)

 

++++Lambda表达式:

    --(参数)=>{语句块}

--Lambda”表达式是一个匿名函数,是一种高级的相似于函数式编程的表达式,Lambda简化了开发中须要编写的代码量。(它能够包含表达式和语句,而且能够用建立委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内敛表达式。)(Lambda表达式都使用Lambda运算符“=>”,读做“goes to”)

--Lambda运算符的左边是输入参数(若是有),右边是表达式或语句块。





###知识点003Event事件

###知识点003Event事件

++框架知识点003Event事件

++++event事件是基于委托(event是在multicast delegate的基础上演变来的)。事件是一种特殊的委托的实例,或者说是受限制的委托,是委托一种特殊应用,在类的外部只能施加+=-=操做符,事件和委托本质上是一个东西。

++++event事件只容许用add(+=)remove(-=)方法来操做,这致使了它不容许在类的外部被直接触发,只能在类的外部适合的时机触发。(委托能够在外部被触发,可是别这么用。)(委托经常使用来表达回调,事件表达外发的接口。)

++++event事件不能够看成形参传递,delegate委托能够。

++++自定义事件的通常步骤:

--步骤1、声明关于事件的delegate委托;(public delegate void YanlzChangeHandler();

--步骤2、声明event事件;(public event YanlzChangeHandler OnYanlzChangeEvent;

--步骤3、编写触发事件的函数;(public void DoChange(){  OnYanlzChangeEvent();  }

--步骤4、建立事件处理程序;(void MyHandlerAlarm(){}

--步骤5、注册事件处理程序;(OnYanlzChangeEvent += MyHandlerAlarm;

--步骤6、在适当的条件下触发事件;(DoChange();


++立钻哥哥:经过一个简单例子熟悉event事件

using System;

namespace YanlzPublisherEvent{

    //出版社

    class MyPublisher{

        public delegate void PublishHandler();    //定义一个委托类型

        public event PublishHandler OnPublishEvent;    //声明一个事件

    

        //事件触发的方法

        public void DoMyIssue(){

            if(null != OnPublishEvent){

                Debug.Log(立钻哥哥:有新刊物更新出版了);

                OnPublishEvent();    //事件触发

            }

        }

    }    //立钻哥哥:class MyPublisher{}

 

    //订阅者

    class MySubscriber{

        //在事件订阅者中定义事件处理程序

        public void Recevie(){

            Debug.Log(立钻哥哥:收到信出版的刊物了);

        }

    }    //立钻哥哥:class MySubscriber{}

 

    class MyStory{

        static void Main(){

            MyPublisher myPub = new MyPublisher();

            MySubscriber mySub = new MySubscriber();

 

            //向事件发行者订阅一个事件

            myPub.OnPublishEvent += new MyPublisher.PublishHandler(mySub.Receive);

            myPub.DoMyIssue();    //触发事件

        }

    }    //立钻哥哥:class MyStory{}

 

}    //立钻哥哥:namespace YanlzPublisherEvent{}


++event事件简单示例:熟悉event事件

//立钻哥哥:经过模拟简单的服务器和客户端订阅和发布

 

//服务器

public class MyServer{

    public event Action<string> MyMsgEvent;    //服务器发布的事件

 

    public void DoMySend(string msg){

        if(null != MyMsgEvent){

            Debug.Log(立钻哥哥:Server推送的消息: + msg);

            MyMsgEvent(msg);

        }

    }

}    //立钻哥哥:public class MyServer

 

//客户端

public class MyClient{

    public MyClient(MyServer myServ){

        myServ.MyMsgEvent += Receive;    //客户端订阅

    }

 

    public void Receive(string msg){

        Debug.Log(立钻哥哥:Client收到了通知: + msg);

    }

}    //立钻哥哥:public class MyClient{}

 

//调用

public class YanlzProgram{

    static void Main(){

        MyServer myServ = new MyServer();

        MyClient myClient = new MyClient(myServ);

        myServ.DoMySend(立钻哥哥:serv发送消息了);

    }

}    //立钻哥哥:public class MyProgram{}


++event事件示例:经过一个猫和老鼠的经典案例熟悉event事件

//立钻哥哥:经过猫和老鼠的案例熟悉event事件

using System;

namesapce YanlzDelegateEvent{

    //定义一个猫类

    class MyCat{

        private string name;    //猫的名字

    

        //构造函数

        public MyCat(string name){

            this.name = name;

        }

 

        public delegate void CatShoutDelegate();    //定义一个委托

        public event CatShoutDelegate CatShoutEvent;    //定义一个事件

 

        //定义一个猫叫的方法

        public void DoMyCatShout(){

            Debug.Log(立钻哥哥:喵喵~,这只猫是{0}, name);

 

            //执行猫叫方法的时候,先判断委托的实例对象是否存在

            if(null != CatShoutEvent){

                CatShoutEvent();    //执行事件的委托

            }

        }

    }    //立钻哥哥:class MyCat{}

 

    class MyMouse{

        private string name;

    

        public MyMouse(string name){

            this.name = name;

        }

 

        public void MyMouseRun(){

            Debug.Log(立钻哥哥:老猫来了,快跑呀! 我是{0}, this.name);

        }

    }    //立钻哥哥:class MyMouse{}

 

    class MyMainClass{

        public static void Main(string[] args){

            MyCat myCat = new MyCat(Tom);

            MyMouse mouse1 = new MyMouse(Jerry);

            MyMouse mouse2 = new MyMouse(Jack);

 

            //MouseRun方法经过示例委托给CatShoutDelegate登记到猫的事件中

            myCat.CatShoutEvent += new Cat.CatShoutDelegate(mouse1.MyMouseRun);

            myCat.CatShoutEvent += new Cat.CatShoutDelegate(mouse2.MyMouseRun);

        

            myCat.DoMyCatShout();    //立钻哥哥:猫来了

        }

    }    //立钻哥哥:class MyMainClass{}

 

}    //立钻哥哥:namespace YanlzDelegateEvent{}


++立钻哥哥带您进入event事件

 

++++event事件机制的两个主体是:发布者(publisher)和订阅者(subscriber)。

--发布者(publisher):发布某个事件的类或结构。

--订阅者(subscriber):注册在事件发生时获得通知的类或结构。

--事件处理程序(event handler):订阅者收到通知时要执行的方法。

--触发(raise)事件:就是发布通知(依次执行委托列表的方法)。

++++示例强化:实现点击一个按钮后,画布上出现一张图片。

--画布类(订阅者)有一个显示图片的方法(事件处理程序),把这个方法添加到按钮(发布者)的事件的委托中,当按钮被点击(触发事件),就执行事件里面的委托,这委托里面就会执行显示图片的方法。

//立钻哥哥:实现点击一个按钮后,画布上出现一张图片

namespace YanlzEventDemo{

    //发布者(publisher

    class MyButton{

        public event EventHandler ButtonClickedEvent;    //EventHander系统推荐使用

    

        public void OnButtonClicked(){

            ButtonClickedEvent(this, null);    //立钻哥哥:触发事件

        }

    }    //立钻哥哥:class MyButton{}

 

    //订阅者

    class MyCanvas{

        private string myPicture = 立钻哥哥:I am a picture!;

   

        public MyCanvas(MyButton myBtn){

            myBtn.ButtonClickedEvent += ShowPicture;    //订阅事件

        }

 

        //事件处理程序(签名要和委托匹配)

        void ShowPicture(object source, EventArgs e){

            Debug.Log(立钻哥哥:picture: + myPicture);

        }

    }    //立钻哥哥:class MyCanvas

 

    class YanlzProgram{

        static void Main(){

            MyButton myButton = new MyButton();

            MyCanvas myCanvas = new MyCanvas(myButton);

 

            myButton.OnButtonClicked();

        }

    }    //立钻哥哥:class YanlzProgram

 

}    //立钻哥哥:namespace YanlzEventDemo{}


++event事件实战:立钻哥哥经过一个示例揭示event事件机理

++++事件:可看作是一个或若干个动做,好比射击事件,包含几个动做:1、子弹上膛(Load),2、拉枪栓(Pull),3、瞄准(Aim),4、扣扳机(Fire)等。

//立钻哥哥:经过这个射击示例,深刻熟悉event事件

using System;

namespace YanlzEventDemo{

    public delegate void ActHandler();

 

    class GunFire{

        public static void GunLoad(){

        }

 

        public static void GunPull(){

        }

 

        public static void GunAim(){

        }

 

        public static void GunFire(){

        }

    }    //立钻哥哥:class GunFire{}

 

    class MySoldier{

        public event ActHandler MyFireEvent;

 

        public void OnFire(){

            MyFireEvent();

        }

    }    //立钻哥哥:class MySoldier{}

 

    class YanlzProgram{

        public static void Main(string[] args){

            MySoldier mySoldier = new MySoldier();

            mySoldier.MyFireEvent += GunFire.GunLoad;

            mySoldier.MyFireEvent += GunFire.GunPull;

            mySoldier.MyFireEvent += GunFire.GunAim;

            mySoldier.MyFireEvent += GunFire.GunFire;

 

            bool canFireCmd = true;    //立钻哥哥:模拟开枪指令

            if(canFireCmd){

                mySolider.OnFire();

            }

        }

    }    //立钻哥哥:class YanlzProgram{}

 

}    //立钻哥哥:namespace YanlzEventDemo{}


++event事件实战:立钻哥哥利用一个demo来加深理解event事件

++++立钻哥哥:经过一个Demo来模拟服务器、客户端的消息推送接收处理。

//立钻哥哥:Demo模拟网络消息处理(Server.csClient.csProrams.cs

 

//立钻哥哥:模拟服务器(YanlzEventDemo/MyServer.cs

using System;

namesapce YanlzEventDemo{

    public delegate void MySendMsgHandler(string msg);    //定义delegate

 

    //模拟服务器:推送消息

    public class MyServer{

        public static event MySendMsgHandler mySendMsgEvent; //事件是委托的实例对象

    

        //服务器端推送消息给客户端

        public void DoSendMsg(string msg){

            Debug.Log(立钻哥哥:服务器开始推送消息了~~~~~);

 

            //不为空,表示客户端订阅了事件(mySendMsgEvent由客户端初始化)

            if(null != mySendMsgEvent){

                mySendMsgEvent(msg);    //执行委托事件(执行它注册的方法

            }

        }

    }    //立钻哥哥:public class MyServer{}

 

}    //立钻哥哥:namespace YanlzEventDemo

 

//立钻哥哥:模拟客户端(YanlzEventDemo/MyClient.cs

using System;

namespace YanlzEventDemo{

    //模拟手机客户端:订阅消息推送事件

    class MyClient{

        //订阅事件:客户端订阅服务器推送消息的功能

        public void MySubscription(){

            Debug.Log(立钻哥哥:客户端订阅了推送事件了-----);

 

            MyServer.mySendMsgEvent += Server_MySendMsgEvent;  //给事件绑定方法

        }

 

        private void Server_MySendMsgEvent(string msg){

            Debug.Log(立钻哥哥:客户端接收到的推送消息:msg: + msg);

        }

    }    //立钻哥哥:class MyClient{}

 

}    //立钻哥哥:namespace YanlzEventDemo{}

 

//立钻哥哥:模拟控制程序(YanlzEventDemo/MyProgram.cs

namespace YanlzEventDemo{

    //模拟控制程序

    public class MyProgram{

        static void Main(string[] args){

            MyClient myClient = new MyClient();

            MyServer myServer = new MyServer();

 

            myClient.MySubscription();    //客户端订阅消息

            myServer.DoSendMsg(立钻哥哥:推送的消息来了~~~);  //服务器推送消息

        }

    }    //立钻哥哥:public class MyProgram{}

 

}    //立钻哥哥:namespace YanlzEventDemo{}


++event事件实战:立钻哥哥经过示例带您了解event事件

++++立钻哥哥:尝试用一个比较通俗的例子拓展event事件的应用场景

//立钻哥哥:模拟水壶烧水事件:(热水器、警报器、显示器)根据水温提示

using System;

namespace YanlzEventDemo{

    public delegate void MyAlarmHandler(int temperature);    //报警委托

    public delegate void MyDisplayHandler(int temperature);    //显示委托

 

    //热水器类

    class MyHeater{

        private int temperature = 10;    //温度

 

        public event MyAlarmHandler OnMyAlarmEvent;    //报警事件

        public event MyDisplayHandler OnMyDisplayEvent;    //显示事件

 

        public void BoildWater(int minute){

            Debug.Log(立钻哥哥:如今水温{0}, this.temperature);

            this.temperature += minute * 10;    //立钻哥哥:模拟水温升高

        

            if(this.temperature >= 95){

                OnMyAlarmEvent(this.temperature);

                OnMyDisplayEvent(this.temperature);

            }

        }

    }    //立钻哥哥:class MyHeater{}

 

    //报警器类

    class MyAlarm{

        public void MyMakeAlert(int temperature){

            Debug.Log(立钻哥哥:滴滴滴,水开了:温度{0}, temperature);

        }

    }    //立钻哥哥:class MyAlarm{}

 

    //显示器类

    class MyDisplay{

        public void MyShowMsg(int temperature){

        Debug.Log(立钻哥哥:动画显示水开了,水温{0}, temperature);

        }

    }

 

    class MyProgram{

        static void Main(string[] args){

            MyHeater myHeater = new MyHeater();    

            MyAlarm myAlarm = new MyAlarm();

            MyDisplay myDisplay = new MyDisplay();

 

            //创建关联

            myHeater.OnMyAlarmEvent += myAlarm.MyMakeAlert;

            myHeater.OnMyDisplayEvent += myAlarm.MyShowMsg;

 

            meHeater.BoilWater(20);    //立钻哥哥:模拟烧水20分钟

        }

    }    //立钻哥哥:class MyProgram{}

 

}    //立钻哥哥:namespace YanlzEventDemo{}





###知识点004EventHandle

###知识点004EventHandle

++框架知识点004EventHandle

++++EventHandle委托是C#预约义的一个事件委托。

namespace System{

    [Serializable]

    [ComVisible(true)]

    public delegate void EventHandler(object sender, EventArgs e);

    //object sender:事件源(System.Object

    //EventArgs e: 不包含事件数据的对象(System.EventArgs

}

++++EventHandle泛型:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

//object sender:事件源(System.Object

//TEventArgs e:包含事件数据的对象(TEventArgs

++++EventHandler是一个预约义的委托,专用于表示不生成数据的事件的事件处理程序方法。(若是事件生成数据,则必须提供本身的自定义事件数据类型,而且必需要建立一个委托,其中第二个参数的类型为自定义类型,要么使用泛型EventHandler委托类并用自定义类型替代泛型类型参数。)

++++EventHandler事件委托:事件就是类或者对象的状态发生改变时,对象或类发出的信息或通知。(发出信息的对象或者类称为“事件源”,对事件处理的方法称为“接收者”)(一般事件源在发出状态改变信息,它并不知道由哪一个事件接收者处理。)(这就须要经过一种机制来协调事件源和接收者,在C++中经过函数指针来完成的,在C#中事件使用委托来为触发时将调用的方法提供类型安全的封装。)

--1、声明一个委托:public delegate void EventHandler(object sender, EventArgs e);

--2、声明一个事件:public event EventHandle OnChangedEvent;

--3、引用一个事件:public DoChanged(EventArgs e){  OnChangeEvent(this, e);  }

--4、定义事件处理函数:public YanlzTest_OnChanged(object sender, EventArgs e){}

--5、订阅事件:ylzClass.OnChangedEvent += new EventHandle(YanlzTest_OnChanged);


++EventHandle委托示例:

//立钻哥哥:EventHandle简单应用场景

using System;

namespace YanlzEventHandlerTest{

    class MyMainProgram{

        public delegate void EventHandler(string a);    //委托

        public static event EventHandler OnYanlzSetCodeEvent;    //事件

    

        static void Main(string[] args){

            MyMainProgram.OnYanlzSetCodeEvent += DoMyGetCode;    //注册

 

            OnYanlzSetCodeEvent(立钻哥哥:触发了);    //触发

        }

 

        public static void DoMyGetCode(string str){

            Debug.Log(立钻哥哥:得到触发消息:{0}, str);

        }

    }    //立钻哥哥:class MyMainProgram{}

 

}    //立钻哥哥:namespace YanlzEventHandlerTest{}


++自定义EventHandle实现参考:了解EventHandle的机制

//立钻哥哥:自定义EventHandle示例

using System;

namespace YanlzEventHandleDemo{

    public class YanlzMyText{

        public string textStr = “”;

        public delegate void YanlzChangedEventHandle(object sender, EventArgs e);

        public event YanlzChangedEventHandle OnChangedEvent;

 

        protected void DoChangedText(EventArgs e){

            if(null != OnChangedEvent){

                OnChangedEvent(this, e);

            }

        }

 

        public string HelloText{

            get{

                return textStr;

            }

            set{

                textStr = value;

                this.DoChangedText(new EventArgs());

            }

        }

 

    }    //立钻哥哥:public class YanlzMyText{}

 

    class MyMainProgram{

        static void Main(string[] args){

            YanlzMyText myText = new YanlzMyText();

            myText.OnChangedEvent += new YanlzMyText.YanlzChangedEventHandle(MyMainTextChange);

 

            //立钻哥哥:循环测试

            string str = “”;

            while(str != quit){

                Console.WriteLine(立钻哥哥:Please Enter a string:);

                str = Console.ReadLine();

                myText.HelloText = str;

            }

        }

 

        public static void MyMainTextChange(object sender, EventArgs e){

            Debug.Log(立钻哥哥:text has been changed : {0}, ((YanlzMyText)sender).HelloText);

        }

 

    }    //立钻哥哥:class MyMainProgram{}

 

}    //立钻哥哥:namespace YanlzEventHandlerDemo{}


++EventHandle事件委托简单示例

//立钻哥哥:经过一个简单的EventHandle事件委托示例熟悉EventHandle机制。

using Sytem;

namespace YanlzEventHandleDemo{

    //事件参数,必须继承类EventArgs

    public class YanlzAddEventData : EventArgs{

        public int a;

        public int b;

    }    //立钻哥哥:public class YanlzAddEventData : EventArgs{}

 

    public class MyEventHandleTest{

        private event EventHandler<YanlzAddEventData> OnYanlzAddEvent;  //事件对象

    

        //初始化事件

        public void InitYanlzAddEvent(EventHandler<YanlzAddEventData> myAddEvent){

            this.OnYanlzAddEvent += new EventHandler<YanlzAddEventData>(myAddEvent);

        }

 

        //触发事件

        public void DoCallAddEvent(){

            if(null != OnYanlzAddEvent){

                YanlzAddEventData myAddED = new YanlzAddEventData();

                myAddED.a = 1;

                myAddED.b = 2;

                OnYanlzAddEvent(this, myAddED);

            }

        }

    }    //立钻哥哥:public class MyEventHandleTest{}

 

    class YanlzTestMainProgram{

        public static void Main(string[] args){

            MyEventHandleTest myTest = new MyEventHandlerTest();

            myTest.InitYanlzAddEvent(MyMainAddEvent);    //传递事件处理函数地址

 

            myTest.DoCallAddEvent();    //触发事件

        }

 

        //加法事件

        public static void MyMainAddEvent(object sender, EventArgs e){

            YanlzAddEventData myData = (YanlzAddEventData)e;

            int c = myData.a + myData.b;

    

            Debug.Log(立钻哥哥:触发事件AddEvent: a + b = {0}, c);

        }

    }    //立钻哥哥:class YanlzTestMainProgram{}

 

}    //立钻哥哥:namespace YanlzEventHandleDemo{}


++使用EventHandler传递参数

++++立钻哥哥:使用自定义控件时,须要对一个控件的click,mouseDown,mouseUp等事件的处理进行从新定义,以知足实际工程应用和要求:

--button1.Click -= new EventHandler(ButtonClick_Handler);

--button1.MouseUp -= new MouseEventHandler(ButtonClick_Handler);

--button1.Click += new EventHandler(ButtonClick_Handler);

--button1.MouseUp += new MouseEventHandler(ButtonUp_Handler);

++++.Net Framework中的事件模型基于事件委托,该委托将事件处理程序链接。

++++引起事件的两个元素:

--1、标识对事件提供响应的方法和委托。

--2、保存事件数据的类:

--public delegate void EventHandler(Object sender, EventArgs e);

--public event EventHandler NoDataEventHandler;





###知识点005Func

###知识点005Func

++框架知识点005Func

++++Func<TResult>委托:封装一个方法,且返回值由TResult参数指定的类型的值。

++++namespace{  public delegate TResult Func<TResult>();  }

++++Func的类型(使用Func委托函数必须带有返回值:TResult返回类型):

--delegate TResult Func<TResult>();

--delegate TResult Func<T, TResult>(T arg);

--delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);

--delegate TResult Func<T1, T2, T3, Tn>(T1, arg1, T2 arg2, T3 arg3, Tn argn);

++++Func委托和Action委托的惟一区别就是代理的方法(函数)有没有返回值:有返回值选择Func委托,没有返回值选择Action委托。


++Func委托简单示例:

//立钻哥哥:简单示例Func委托

 

//1delegate TResult Func<TResult>();

Func<string> myFunc01 = delegate(){

    return 立钻哥哥:这是Func<TResult>委托返回的结果。

};

string result01 = myFunc01();

Debug.Log(立钻哥哥:输出结果result: + result01);

 

//2delegate TResult Func<T, TResult>(T arg);

Func<string, string> myFunc02 = delegate(string s){

    return s.ToLower();

};

string result02 = myFunc02(LOVEZUANZUAN);

Debug.Log(立钻哥哥:输出结果result: + result02);

 

//3delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);

Func<string, string, string> myFunc03 = delegate(string str1, string str2){

    return str1 +   + str2;

};

Debug.Log(立钻哥哥:输出结果result + myFunc03(立钻哥哥, Func<T1, T2, TResult>));


++Func<TResult>委托(delegate显式定义=>Func<TResult>=>匿名方法=>Lambda表达式)

++++立钻哥哥尝试利用四种方式来剖析引入Func<TResult>

//1、立钻哥哥:delegate显式定义

using System;

delegate bool YanlzWriteMethodHandler();    //立钻哥哥:delegate显式定义

 

public class YanlzMainTestDelegate{

    public class MyOutputTarget{

        public bool SendToFile(){

            try{

                string myFileName = Path.GetTempFileName();

                StreamWirte myStreamWriter = new StreamWriter(myFileName);

                myStreamWriter.WriteLine(立钻哥哥:Hello World!);

                myStreamWriter.Close();

                return true;

            }catch{

                return false;

            }

        }

    }

 

    public static void Main(){

        MyOutputTarget myOutput = new MyOutputTarget();

        YanlzWriteMethodHandler myMethodCall = myOutput.SendToFile;

        if(myMethodCall()){

            Debug.Log(立钻哥哥:Success!);

        }else{

            Debug.Log(立钻哥哥:File write operation failed.);

        }

    }

 

}    //立钻哥哥:public class YanlzMainTestDelegate{}

 

//2、立钻哥哥:使用Func<TResult>

using System;

//delegate bool YanlzWriteMethodHandler();     //立钻哥哥:delegate显式定义

 

public class YanlzMainTestDelegate{

    public static void Main(){

        MyOutputTarget myOutput = new MyOutputTarget();

        //YanlzWriteMethodHandler myMethodCall = myOutput.SendToFile;    //显式定义

        Func<bool> myMethodCall = myOutput.SendToFile;    //使用Func<TResult>

    

        if(myMethodCall()){

             Debug.Log(立钻哥哥:Success!);

        }else{

             Debug.Log(立钻哥哥:File write operation failed.);

        }

    }

 

}    //立钻哥哥:public class YanlzMainTestDelegate{}

 

//3、立钻哥哥:使用Func<TResult>和匿名方法

using System;

//delegate bool YanlzWriteMethodHandler();     //立钻哥哥:delegate显式定义

 

public class YanlzMainTestDelegate{

    public static void Main(){

        MyOutputTarget myOutput = new MyOutputTarget();

        //YanlzWriteMethodHandler myMethodCall = myOutput.SendToFile;    //显式定义

        //Func<bool> myMethodCall = myOutput.SendToFile;    //使用Func<TResult>

        Func<bool> myMethodCall = delegate( return myOutput.SendToFile);    //匿名

    

        if(myMethodCall()){

             Debug.Log(立钻哥哥:Success!);

        }else{

            Debug.Log(立钻哥哥:File write operation failed.);

        }

    }

 

}    //立钻哥哥:public class YanlzMainTestDelegate{}

 

//4、立钻哥哥:使用Func<TResult>lambda

using System;

//delegate bool YanlzWriteMethodHandler();     //立钻哥哥:delegate显式定义

 

public class YanlzMainTestDelegate{

    public static void Main(){

        MyOutputTarget myOutput = new MyOutputTarget();

        //YanlzWriteMethodHandler myMethodCall = myOutput.SendToFile;    //显式定义

        //Func<bool> myMethodCall = myOutput.SendToFile;    //使用Func<TResult>

        //Func<bool> myMethodCall = delegate( return myOutput.SendToFile);    //匿名

        Func<bool> myMethodCall = ()=> myOutput.SendToFile;    //Lambda表达式

    

        if(myMethodCall()){

            Debug.Log(立钻哥哥:Success!);

        }else{

            Debug.Log(立钻哥哥:File write operation failed.);

        }

    }

 

}    //立钻哥哥:public class YanlzMainTestDelegate{}





###知识点006Lambda表达式

###知识点006Lambda表达式

++框架知识点006Lambda表达式

++++Lambda”表达式是一个匿名函数,是一种高效的相似于函数式编程的表达式,Lambda简化了开发中须要编写的代码量。它能够包含表达式和语句,而且能够用建立委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内敛表达式。(Lambda表达式使用运算符“=>”,读做“goes to”)

++++Lambda运算符的左边是输入参数(若是有),右边是表达式或语句块。

++++函数MyFunc(string a, string b){}Lambda表达式:(a, b)=>{}

++++函数bool MyMax(int a, int b){  return a > b ? a : b;  }

--Lambda表达式:(int a, int b)=>{  return a > b ? a : b;  }

++++delegate(x,y){  return x*y;  },用Lambda表达式:(x,y)=>x*y;

++++delegate(int x){  return x*x;  },用Lambda表达式:(int x)=>{ return x*x; };

++++Lambda表达式是一种可用于建立委托或表达式目录树类型的匿名函数。(经过使用Lambda表达式,能够写入可做为参数传递或做为函数调用值返回的本地函数。)(若要建立Lambda表达式,须要在Lambda运算符=>左侧指定输入参数,而后在另外一侧输入表达式或语句块。)


++Lambda输入参数(()arg(arg1, arg2)

++++1、无参数使用()()=>DoYanlzMethod();

++++2、一个参数直接写出参数名: arg=>arg*arg;

++++3、多个参数使用,分割:(arg1, arg2)=>arg1==arg2;

++++4、参数类型没法推断时能够显式指定:(string arg1, char arg2)=>arg1.Split(arg2);

++++拓展:

(arg1, arg2)=>{

        if(arg1 == arg2){

            return 0;

        }

 

        return arg1 > arg2 ? 1 : -1;

}


++初识Lambda表达式:

//立钻哥哥:引入Lambda

class YanlzLambda{

    public delegate void MyDelegateHandle00();    //不带参数的委托

    public delegate void MyDelegateHandle01(string name);    //带参数的委托

    public delegate int myDelegateHandle02(int x, int y);    //有参数有返回值的委托

}

 

MyDelegate01 myDelegate01 = (x)=>{

    Debug.Log(立钻哥哥:这是一个用Lambda表达式的委托,参数为: + x);

};

myDelegate01(立钻哥哥);    //调用

 

MyDelegate03 myDelegate03 = (x, y)=>{

    Debug.Log(立钻哥哥:这是一个用Lambda表达式委托带两个参数,和返回值);

    return x + y;

};

Debug.Log(立钻哥哥:输出结果: + myDelegate03(20, 30));


++Lambda表达式(C#编程)

++++立钻哥哥:Lambda表达式是一种可用于建立委托或表达式目录树类型的匿名函数。(经过使用Lambda表达式,能够写入可做为参数传递或做为函数调用值返回的本地函数。)(若要建立Lambda表达式,须要在Lambda运算符=>左侧指定输入参数,而后在另外一侧输入表达式或语句块。)

//立钻哥哥:建立Lambda表达式

delegate int MyDelegateHandle(int i);

static void Main(string[] args){

    MyDelegateHandle myDelegate = x=> x * x;

    int j = myDelegate(5);    //立钻哥哥:j = 25

}

++++Lambda表达式中的变量范围:在定义lambda函数的方法内或包含Lambda表达式的类型内,Lambda能够引用范围内的外部变量。(以这种方式捕获的变量将进行存储以备在lambda表达式中使用,即便在其余状况下,这些变量将超出范围并进行垃圾回收。)(必须明确地分配外部变量,而后才能在lambda表达式中使用该变量)

//立钻哥哥:Lambda表达式规则演示

delegate bool MyDelegateHandle01();

delegate bool MyDelegateHandle02(int i);

 

class YanlMainTest{

    MyDelegateHandle01 myDelegate01;

    MyDelegateHandle02 myDelegate02;

 

    public void MyTestMethod(int input){

        int j = 0;

        myDelegate01 = ()=>{  j = 10;  return j > input;  }

        myDelegate02 = (x)=>{  return x == j;  }

 

        Debug.Log(立钻哥哥:j = {0}, j);    //立钻哥哥:j=0;delegate未调用)

 

        bool boolResult = myDelegate01();    //立钻哥哥:调用delegate

        Debug.Log(立钻哥哥:j={0}, b={1}, j, boolResult);    //立钻哥哥:j=10, b=true;

    }

 

    static void Main(){

        YanlzMainTest myTest = new YanlzMainTest();

        myTest.MyTestMethod(5);

 

        bool result = myTest.myDelegate02(10);

        Debug.Log(立钻哥哥:result: + result);    //立钻哥哥:输出:true

    }

}

++++适用于Lambda表达式中的变量范围:

--捕获的变量将不会被做为垃圾回收,直至引用变量的委托符合垃圾回收的条件。

--在外部方法中看不到lambda表达式内引入的变量。

--Lambda表达式没法从封闭方法中直接捕获inrefout参数。

--Lambda表达式中的返回语句不会致使封闭方法返回。

--若是跳转语句的目标在块外部,则lambda表达式不能包含位于lambda函数内部的goto语句、break语句、continue语句等。(一样,若是目标在块内部,则在lambda函数块外部使用跳转语句也是错误的。)


++lambda应用C#排序

//立钻哥哥:经过一个C#排序熟悉lambda表达式

using System;

namespace YanlzLambdaLearn{

    public class MyMainProgram{

        public static List<KeyValuePair<int, string>> list_type;

        static Dictionary<int, string> type_value = new Dictionary<int, string>();

 

        public static void Main(string[] args){

            type_value = addKey(type_value);

            list_type = new List<KeyValuePair<int, string>>(type_value);

 

            list_type.Sort((sort1, sort2)=>{

                if(sort1.Key > sort2.Key){

                    return 1;

                }else if(sort1.Key == sort2.Key){

                    return 0;

               }else{

                    return -1;

               }

           });

        }

 

        public static Dictionary<int, string> addKey(Dictionary<int, string> dic){

            dic.Add(5, int);

            dic.Add(4, float);

            dic.Add(6, double);

            dic.Add(1, short);

            dic.Add(7, long);

 

            return dic;

        }

 

    }    //立钻哥哥:public class MyMainProgram{}

 

}    //立钻哥哥:namespace YanlzLambdaLearn{}





###框架知识点007Type

###框架知识点007Type

++框架知识点007Type

++++Type类:https://msdn.microsoft.com/zh-cn/library/system.type(v=vs.110).aspx

++++Type类:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。

using System;

namespace System{

    [ClassInterface(ClassInterfaceType.None), ComDefaultInterface(typof(_Type)), ComVisible(true)]

    [Serializable]

    public abstract class Type : MemberInfo, _Type, IReflect{

        //Static Fields

        //Static Properties

        //Properties

        //Constructors

        //static Methods

        //Methods

    }    //立钻哥哥:public abstract class Type : MemberInfo, _Type, IReflect{}

}    //立钻哥哥:namespace System{}

++++C#中经过Type类能够访问任意数据类型信息。

++++【获取给定类型的Type引用】:

--1、使用typeof运算符,如:Type t = typeof(int);

--2、使用GetType()方法,如:int i;  Type t = i.GetType();

--3、使用Type类静态方法GetType(),如:Type t = Type.GetType(System.Double);

++++Type的属性】:

--1Name:数据类型名;

--2FullName:数据类型的彻底限定名,包括命名空间;

--3Namespace:数据类型的命名空间;

--4BaseType:基类基本类型;

--5UnderlyingSystemType:映射类型;

++++Type的方法】:

--GetMethod():返回一个方法的信息;

--GetMethods():返回全部方法的信息;

++++Type类的重要方法:

//立钻哥哥:列举几个比较重要的Type类信息

using System;

using System.Reflection;

namespace System{

    public abstract class Type : MemberInfo, _Type, IReflect{

        public abstract Type BaseType{  get;  }

        public abstract string FullName{  get;  }

        public bool IsClass{  get;  }

        public bool IsPublic{  get;  }

        public abstract string NameSpace{  get;  }

        public static Type GetType(string typeName, bool throwOnError, bool ignoreCase);

        public static Type GetType(string typeName, bool throwOnError);

        public static Type GetType(string typeName);

        public override bool Equals(object o);

        public bool Equals(Type o);

        public MemberInfo[] GetMember(string name);

        public MemberInfo[] GetMembers();

        public MethodInfo[] GetMethods();

        public override string ToString();

    }

}


++Type类示例参考

 

++++Retrieving a Type object

//立钻哥哥:检索Type类型

using System;

public class YanlzMainExample{

    public static void Main(){

        object[] values = {  立钻哥哥, true, 2008, 199.99, w  };

        foreach(var value in values){

            Console.WriteLine(立钻哥哥:{0}-type{1}, value, value.GetType().Name);

        }

    }

    //立钻哥哥n- type String

    //true - type Boolean

    //2008 - type Int32

    //199.99 - type Double

    //w - type Char

}

 

++++Comparing type objects for equality:

//立钻哥哥:比较Type类型

using System;

public class YanlzTypeMainExample{

    public static void Main(){

        long num1 = 1635499;

        int num2 = 16208;

        double num3 = 1639.99;

        long num4 = 193688779;

 

        Type t = num1.GetType();   //立钻哥哥:得到Type类型

    

        //立钻哥哥:类型比较

        Console.WriteLine(equal:{0}, Object.ReferenceEquals(t, num2.GetType()));  //False

        Console.WriteLine(equal:{0}, Object.ReferenceEquals(t, num3.GetType()));  //False 

        Console.WriteLine(equal:{0}, Object.ReferenceEquals(t, num4.GetType()));  //True

    }

}


++C#typeofGetType()的区别

++++立钻哥哥:C#中任何对象都具备GetType()方法,它的做用和typeof相同,返回Type类型的当前对象的类型。(都是为了获取某个实例具体引用的数据类型System.Type

++++typeofGetType的区别:

--1typeof是运算符,GetType是方法;

--2GetType()是基类System.Object的方法(只有创建一个实例以后才能被调用);

--3typeof的参数只能是intstring、自定义类型,不能是实例;

--4GetType()typeof都返回System.Type的引用;

--5typeof:获得一个classType

--6GetType():获得一个class的实例的Type

++++GetType()方法是基类System.Object的一个方法:

//立钻哥哥:咱们来看看Object基类

using System;

namespace System{

    public class Object{

        //Constructors

        public Object();

 

        //Static Methods

        public static bool Equals(object objA, object objB);

        internal static extern bool InternalEquals(object objA, object objB);

        internal static extern int InternalGetHashCode(object obj);

        public static bool ReferenceEquals(object objA, object objB);

 

        //Methods

        public virtual bool Equals(object obj);

        private void FieldGetter(string typeName, string fieldName, ref object val);

        private void FieldSetter(string typeName, string fieldName, object val);

        protected override void Finalize();

        private FieldInfo GetFieldInfo(string typeName, string fieldName);

        public FieldInfo GetFieldInfo(string typeName, string fieldName);

        public virtual int GetHashCode();

        public extern Type GetType();    //立钻哥哥:fixhere

        protected extern object MemberwiseClone();

        public virtual string ToString();

 

    }    //立钻哥哥:public class Object{}

}    //立钻哥哥:namespace System{}

++++System.Type类】:定义了不少成员,能够用来检查某个类型的元数据,它们返回的类型大多位于System.Reflection命令空间中。(Type.GetMethods()返回一个MethodInfo类型的数组)(Type.GetFields返回一个FieldInfo类型的数组)

++++【使用System.Object.GetType()获得Type引用】:可使用多种方法获得一个Type类的实例。可是,因为Type是一个抽象类,不能直接使用new关键字建立一个Type对象。(咱们首选使用System.Object定义的GetType()方法,它返回一个表示当前对象元数据的Type类的实例。)

++++使用自定义类实例获得类型信息:

YanlzClass myClass = new YanlzClass();    //立钻哥哥:自定义的类

Type mytype = myClass.GetType();

MethodInfo[] methodInfo = myType.GetMethods();

MemberInfo[] memberInfo = myType.GetMembers();


++C#反射之Type

++++立钻哥哥:反射的做用:查看和遍历类型和类型的元数据;动态建立类型实例,动态的调用所建立的实例方法和字段,属性,延迟绑定方法和属性。

++++反射的核心类是Type类:封装了关于类型的元数据,是进行反射的入口。(当得到了类型的Type对象后,能够根据Type提供的属性和方法得到这个类型的信息,包括字段,属性,事件,参数,构造函数等。)

++++Type t = Type.GetType(System.IO.Stream);    //立钻哥哥输出:System.IO.Stream

++++Type t = typeof(System.IO.Stream);    //立钻哥哥输出:System.IO.Stream

++++string name = 立钻哥哥;  Type t = name.GetType();    //立钻哥哥输出:System.String

++++YanlzClass myClass = new YanlzClass();  Type t = myClass.GetType();  //YanlzNS.YanlzClass





###知识点008:索引器(this[string key]

###知识点008:索引器(this[string key]





 

++立钻哥哥推荐的拓展学习连接(Link_Url

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++++框架知识点http://www.javashuo.com/article/p-eufbowgf-u.html

++++游戏框架(UI框架夯实篇)http://www.javashuo.com/article/p-cvemoigb-cu.html

++++游戏框架(初探篇)http://www.javashuo.com/article/p-zfpoilbc-hy.html

++++设计模式简单整理http://www.javashuo.com/article/p-rngqugib-hg.html

++++U3D小项目参考https://blog.csdn.net/vrunsoftyanlz/article/details/80141811

++++UML类图http://www.javashuo.com/article/p-sxberuew-bm.html

++++Unity知识点0001http://www.javashuo.com/article/p-ryvdxxjr-ep.html

++++U3D_Shader编程(第一篇:快速入门篇)http://www.javashuo.com/article/p-kyppgrac-gz.html

++++U3D_Shader编程(第二篇:基础夯实篇)http://www.javashuo.com/article/p-qkyowtli-hv.html

++++Unity引擎基础http://www.javashuo.com/article/p-beommoeb-ka.html

++++Unity面向组件开发http://www.javashuo.com/article/p-eigmuvut-dt.html

++++Unity物理系统http://www.javashuo.com/article/p-nqvvciwv-kd.html

++++Unity2D平台开发http://www.javashuo.com/article/p-ycaagdtj-hs.html

++++UGUI基础http://www.javashuo.com/article/p-rukxwckw-mc.html

++++UGUI进阶http://www.javashuo.com/article/p-wcatruhq-gt.html

++++UGUI综合http://www.javashuo.com/article/p-dkccmqii-gg.html

++++Unity动画系统基础http://www.javashuo.com/article/p-mbrdouxy-dq.html

++++Unity动画系统进阶http://www.javashuo.com/article/p-aqaqpbkh-bp.html

++++Navigation导航系统http://www.javashuo.com/article/p-dswwllas-t.html

++++Unity特效渲染http://www.javashuo.com/article/p-ckojjyfj-bp.html

++++Unity数据存储http://www.javashuo.com/article/p-bvlzynso-m.html

++++Unity中Sqlite数据库http://www.javashuo.com/article/p-ejutsbxl-ca.html

++++WWW类和协程http://www.javashuo.com/article/p-dbwmhsav-cy.html

++++Unity网络http://www.javashuo.com/article/p-sqrlntgh-dw.html

++++C#事件http://www.javashuo.com/article/p-zmwruvql-gm.html

++++C#委托http://www.javashuo.com/article/p-uozpymaf-gh.html

++++C#集合http://www.javashuo.com/article/p-sfqfdqsf-ex.html

++++C#泛型http://www.javashuo.com/article/p-xrttqngo-ee.html

++++C#接口http://www.javashuo.com/article/p-vhlfplgv-dm.html

++++C#静态类https://blog.csdn.net/vrunsoftyanlz/article/details/78630979

++++C#中System.String类http://www.javashuo.com/article/p-olslkfao-cq.html

++++C#数据类型http://www.javashuo.com/article/p-hmabbtmc-ba.html

++++Unity3D默认的快捷键http://www.javashuo.com/article/p-wuwcrclr-s.html

++++游戏相关缩写http://www.javashuo.com/article/p-mwacxwca-gm.html

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/


--_--VRunSoft : lovezuanzuan--_--