C#高级语法

委托

委托就是指针函数,委托的定义与类的属性定义类似都必须在类的方法体进行。

委托的定义:  
  
class Program  
  
    {  
  
        //定义委托:委托不能在方法体内定义。  
  
        public delegate string PrintSomething(string data);  
  
        static void Main(string[] args)  
  
        {  
  
   
  
        }  
  
    }  
  
   
  
使用委托:  
  
        static void Main(string[] args)  
  
        {  
  
            //HelloWorld级别的委托  
  
            PrintSomething PrintFruit = new PrintSomething(Do_1);  
  
            Console.WriteLine(PrintFruit("123"));  
  
}  
  
   
  
执行结果:  
  
you want to print the data:123  

委托数组

class Program  
  
{  
  
  
  
    //定义委托数组  
  
    public delegate void BlukPrintSomething();  
  
  
  
      
  
  
  
    static void Main(string[] args)  
  
    {  
  
        //委托数组  
  
        BlukPrintSomething[] bluckPrintSomething = new BlukPrintSomething[3]{  
  
        BlukPrintSomething_1,BlukPrintSomething_2,BlukPrintSomething_3  
  
        };  
  
  
  
        foreach (BlukPrintSomething bps in bluckPrintSomething)  
  
        {  
  
            bps();  
  
        }  
  
  
  
        Console.ReadKey();  
  
  
  
    }  
  
  
  
    static void BlukPrintSomething_1()  
  
    {  
  
        Console.WriteLine("Apple");  
  
    }  
  
  
  
    static void BlukPrintSomething_2()  
  
    {  
  
        Console.WriteLine("Orange");  
  
    }  
  
  
  
    static void BlukPrintSomething_3()  
  
    {  
  
        Console.WriteLine("Banana");  
  
    }  
  
  
  
}  
委托数组

 

Action<T>和Func<T>

这两个类型可以理解为便捷委托,Action<T>代表没返回值的委托。Func<T>代表有返回值的委托。

 

class Program  
  
    {  
  
        static void Main(string[] args)  
  
        {  
  
            //Action<T> 和Func<T> 委托  
  
            //Action<T> 就是一个便捷类型,让我们省去了定义一个委托类型的步骤  
  
           //Action<string,string> tmp 等效于delegate void myDelegate(string,  
  
string)   
  
Do_2(Do_3);  
  
   
  
            //Func<T>也是一个便捷类型,只不过该类型能具有返回值  
  
            //Func<int,string>等效与 delegate string myDelegate(int)  
  
            Console.WriteLine(Do_4(Do_5));           
  
            Console.ReadKey();  
  
   
  
        }  
  
   
  
        static string Do_1(string data)  
  
        {  
  
            return "you want to print the data:" + data;  
  
        }  
  
   
  
        static void Do_2(Action<string,string,string,string> data)  
  
        {  
  
            data("1", "2", "3", "4");  
  
        }  
  
   
  
        static void Do_3(string d1, string d2, string d3, string d4)  
  
        {  
  
            Console.WriteLine(d1 + d2 + d3 + d4);  
  
        }  
  
   
  
        static string Do_4(Func<string,string,string,string,string> data)  
  
        {  
  
            return data("1", "2", "3", "4");  
  
        }  
  
   
  
        static string Do_5(string d1, string d2, string d3, string d4)  
  
        {  
  
            return d1 + "|" + d2 + "|" + d3 + "|" + d4;  
  
        }  
  
          
  
    }//class  
Action Func

 

多播委托

    一个函数委托绑定多个实现函数,调用一个委托则可以调用绑定在该委托上的所有实现函数

class Program  
  
    {  
  
        static void Main(string[] args)  
  
        {  
  
            BlukPrintSomething bluckPrintSomething = new BlukPrintSomething(BlukPrintSomething_1);  
  
            bluckPrintSomething += BlukPrintSomething_2;  
  
            bluckPrintSomething += BlukPrintSomething_3;  
  
            bluckPrintSomething();  
  
   
  
            Console.ReadKey();              
  
   
  
        }  
  
   
  
        static void BlukPrintSomething_1()  
  
        {  
  
            Console.WriteLine("Apple");  
  
        }  
  
   
  
        static void BlukPrintSomething_2()  
  
        {  
  
            Console.WriteLine("Orange");  
  
        }  
  
   
  
        static void BlukPrintSomething_3()  
  
        {  
  
            Console.WriteLine("Banana");  
  
        }  
  
          
  
    }  
  
   
  
执行结果:  
  
Apple  
  
Orange  
  
Banana  

匿名方法

    不长期保存的方法,也许只能使用一次。对那些只使用一次的方法,主要用来解决程序在运行时的需求。

class Program  
  
    {  
  
   
  
        public delegate void BlukPrintSomething();  
  
   
  
        static void Main(string[] args)  
  
        {  
  
            BlukPrintSomething bluk = delegate()  
  
            {  
  
                Console.WriteLine("niming func!");  
  
            };  
  
   
  
            bluk();  
  
            Console.ReadKey();  
  
        }  
  
         
  
    }  
  
   
  
执行结果:  
  
niming func!  

Lambada表达式

Lambada表达式就是一个便捷的匿名函数。"=>"箭头左边是传进匿名函数的参数,而右边则是处理参数的逻辑。

 

class Program  
  
    {  
  
   
  
        public delegate string PrintSomething(string data);  
  
   
  
        static void Main(string[] args)  
  
        {  
  
            PrintSomething printSomething = a => string.Format("this data:{0} if from Lambada", a);  
  
            Console.WriteLine(printSomething("GB"));  
  
   
  
            Console.ReadKey();           
  
   
  
        }  
  
         
  
    }  
  
   
  
执行结果:  
  
this data:GB if from Lambada  

事件

事件与委托类似,不同的是事件会将调用则及调用环境作为参数传递给绑定的处理程序。

class Program  
  
    {  
  
        //定义事件  
  
//不接受参数的事件  
  
        public static event EventHandler NotifyAnyone;  
  
   
  
//接受一个参数的事件  
  
        public static event EventHandler<GhostEventArgs> NotifyAnyone2;  
  
          
  
static void Main(string[] args)  
  
        {  
  
            //事件  
  
            //为事件添加订阅者,这个是匿名的订阅者  
  
            NotifyAnyone += delegate(object sender, EventArgs e)  
  
            {  
  
                Console.WriteLine("NotifyAnyone event is trigger!");  
  
            };  
  
            NotifyAnyone(new object(),new EventArgs());  
  
              
  
   
  
            //添加订阅或取消订阅。这里.Net已经将观察者模式很好的结合起来了。  
  
              
  
            NotifyAnyone += NotifyAnyoneNoParam_1;  
  
            NotifyAnyone += NotifyAnyoneNoParam_2;  
  
            NotifyAnyone += NotifyAnyoneNoParam_3;  
  
            NotifyAnyone(new object(), new EventArgs());  
  
            Console.WriteLine();  
  
            NotifyAnyone -= NotifyAnyoneNoParam_3;  
  
            NotifyAnyone(new object(), new EventArgs());  
  
              
  
   
  
            //带参数的事件订阅与取消  
  
              
  
            GhostEventArgs e1 = new GhostEventArgs();  
  
            e1.FireTime = DateTime.Now;  
  
   
  
            NotifyAnyone2 += NotifyAnyoneHaveParam_1;  
  
            NotifyAnyone2 += NotifyAnyoneHaveParam_2;  
  
            NotifyAnyone2 += NotifyAnyoneHaveParam_3;  
  
            NotifyAnyone2(new object(), e1);  
  
            Console.WriteLine();  
  
            NotifyAnyone2 -= NotifyAnyoneHaveParam_3;  
  
            NotifyAnyone2(new object(), e1);  
  
   
  
            Console.ReadKey();  
  
        }  
  
   
  
        static void NotifyAnyoneNoParam_1(object sender, EventArgs e)  
  
        {  
  
            Console.WriteLine(" Event NotifyAnyoneNoParam_1 Was Trigger!");  
  
        }  
  
   
  
        static void NotifyAnyoneNoParam_2(object sender, EventArgs e)  
  
        {  
  
            Console.WriteLine(" Event NotifyAnyoneNoParam_2 Was Trigger!");  
  
        }  
  
   
  
        static void NotifyAnyoneNoParam_3(object sender, EventArgs e)  
  
        {  
  
            Console.WriteLine(" Event NotifyAnyoneNoParam_3 Was Trigger!");  
  
        }  
  
   
  
        static void NotifyAnyoneHaveParam_1(object sender, GhostEventArgs e)  
  
        {  
  
            Console.WriteLine(string.Format("this event is trigger on {0}", e.FireTime));  
  
        }  
  
   
  
        static void NotifyAnyoneHaveParam_2(object sender, GhostEventArgs e)  
  
        {  
  
            Console.WriteLine(string.Format("this event is trigger on {0}", e.FireTime));  
  
        }  
  
   
  
        static void NotifyAnyoneHaveParam_3(object sender, GhostEventArgs e)  
  
        {  
  
            Console.WriteLine(string.Format("this event is trigger on {0}", e.FireTime.ToString()));  
  
        }  
  
         
  
    }  
  
   
  
GhostEventArgs:  
  
    class GhostEventArgs:EventArgs  
  
    {  
  
        public DateTime FireTime { get; set; }  
  
    }  
  
   
  
执行结果:  
  
NotifyAnyone event is trigger!  
  
NotifyAnyone event is trigger!  
  
 Event NotifyAnyoneNoParam_1 Was Trigger!  
  
 Event NotifyAnyoneNoParam_2 Was Trigger!  
  
 Event NotifyAnyoneNoParam_3 Was Trigger!  
  
   
  
NotifyAnyone event is trigger!  
  
 Event NotifyAnyoneNoParam_1 Was Trigger!  
  
 Event NotifyAnyoneNoParam_2 Was Trigger!  
  
this event is trigger on 2012/2/23 15:50:22  
  
this event is trigger on 2012/2/23 15:50:22  
  
this event is trigger on 2012/2/23 15:50:22  
  
   
  
this event is trigger on 2012/2/23 15:50:22  
  
this event is trigger on 2012/2/23 15:50:22  
事件

 

动态语言(DynamicObject)

    Var类型与dynamic类型的区别:Var类型在为其赋值前类型不确定,但赋值后类型则定下来了不能进行修改。而Dynamic类型却没有这样的限制,可以在任何时候存放任何类型的东西。

var data = "this is a string";  
  
    Console.WriteLine(data);  
  
    //data = 1;//这句无法通过  
  
    Console.WriteLine(data);  
  
    
  
    dynamic data2 = "this is a string";  
  
    Console.WriteLine(data2);  
  
    data2 = 1;  
  
    Console.WriteLine(data2);  
  
    data2 = new Object();  
  
    Console.WriteLine(data2);  
  
   
  
执行结果:  
  
this is a string  
  
this is a string  
  
   
  
this is a string  
  
1  
  
System.Object  

ExpandoObject(扩展对象)

    这个类型的对象与JavaScript中的变量类似,可以动态的扩展。

dynamic data = new ExpandoObject();  
  
   
  
    data.FirstAttribute = "FirstAttribute";  
  
    data.SecondAttribute = "SecondAttribute";  
  
    data.ThirdAttribute = "ThirdAttribute";  
  
   
  
    ArrayList nums = new ArrayList();  
  
    for (int i = 1; i <= 10; i++)  
  
    {  
  
        nums.Add(i);  
  
    }  
  
   
  
    data.Nums = nums;  
  
    foreach (int tmp in data.Nums)  
  
    {  
  
        Console.WriteLine(tmp);  
  
    }  
  
   
  
    Console.WriteLine(data.FirstAttribute);  
  
    Console.WriteLine(data.SecondAttribute);  
  
    Console.WriteLine(data.ThirdAttribute);  
  
   
  
    Action GB = delegate() { GhostBear2(); };  
  
    data.MyMethod2 = GB;  
  
    data.MyMethod2();  
  
   
  
    Action<string> GhostBear = a => Console.WriteLine(a);  
  
    data.MyMethod = GhostBear;  
  
    data.MyMethod("Go!Go!Fighting!");  
  
             
  
   
  
    //被调用的方法体  
  
    public static void GhostBear2()  
  
    {  
  
        Console.WriteLine("This is dynamic method.");  
  
    }  
  
   
  
   
  
   
  
执行结果:  
  
1  
  
2  
  
3  
  
4  
  
5  
  
6  
  
7  
  
8  
  
9  
  
10  
  
FirstAttribute  
  
SecondAttribute  
  
ThirdAttribute  
  
This is dynamic method.  
  
Go!Go!Fighting!  
扩展对象

 

DynamicObject(实现自己的可扩展类型)

    自己也可以实现扩展类型,但没有系统自带的扩展类型(ExpandoObject)好用。

  1 using System;  
  2   
  3 using System.Collections.Generic;  
  4   
  5 using System.Linq;  
  6   
  7 using System.Text;  
  8   
  9    
 10   
 11 using System.Dynamic;  
 12   
 13    
 14   
 15 namespace chapter12  
 16   
 17 {  
 18   
 19     class MyDynamicObject:DynamicObject  
 20   
 21     {  
 22   
 23         Dictionary<string, object> data = new Dictionary<string, object>();  
 24   
 25    
 26   
 27         /// <summary>  
 28   
 29         ///   
 30   
 31         /// </summary>  
 32   
 33         /// <param name="binder">传进来的参数,包含了调用信息</param>  
 34   
 35         /// <param name="result">返回包含的对象</param>  
 36   
 37         /// <returns>返回是否成功</returns>  
 38   
 39         public override bool TryGetMember(GetMemberBinder binder, out object result)  
 40   
 41         {  
 42   
 43             bool isContain = false;  
 44   
 45             if (data.ContainsKey(binder.Name))  
 46   
 47             {  
 48   
 49                 result = data[binder.Name];  
 50   
 51                 isContain = true;  
 52   
 53             }  
 54   
 55             else  
 56   
 57             {  
 58   
 59                 result = "Not Find";  
 60   
 61             }  
 62   
 63             return isContain;  
 64   
 65         }  
 66   
 67    
 68   
 69         /// <summary>  
 70   
 71         ///   
 72   
 73         /// </summary>  
 74   
 75         /// <param name="binder">传进来的参数,包含了调用信息</param>  
 76   
 77         /// <param name="value">传进来的参数,包含了调用信息</param>  
 78   
 79         /// <returns></returns>  
 80   
 81         public override bool TrySetMember(SetMemberBinder binder, object value)  
 82   
 83         {  
 84   
 85             bool result = false;  
 86   
 87             if (!data.ContainsKey(binder.Name))  
 88   
 89             {  
 90   
 91                 data[binder.Name] = value;  
 92   
 93                 result = true;  
 94   
 95    
 96   
 97             }  
 98   
 99             return result;  
100   
101         }  
102   
103    
104   
105         /// <summary>  
106   
107         ///   
108   
109         /// </summary>  
110   
111         /// <param name="binder">传进来的参数,包含了调用信息</param>  
112   
113         /// <param name="args">传进来的参数,包含了调用信息</param>  
114   
115         /// <param name="result">方法体执行后返回的结果</param>  
116   
117         /// <returns>调用是否成功</returns>  
118   
119         public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)  
120   
121         {  
122   
123             dynamic tmp = data[binder.Name];  
124   
125             result = null;  
126   
127    
128   
129             tmp((string)args[0]);  
130   
131              
132   
133             return true;  
134   
135         }  
136   
137     }  
138   
139 }  
140   
141    
142   
143 调用代码:  
144   
145     dynamic myDynamicObject = new MyDynamicObject();  
146   
147               
148   
149     myDynamicObject.FirstAttribute = "FirstAttribute";  
150   
151               
152   
153     Action<string> myMethod = a => Console.WriteLine(a);  
154   
155     myDynamicObject.myMethod = myMethod;  
156   
157    
158   
159     Console.WriteLine(myDynamicObject.FirstAttribute);  
160   
161     myDynamicObject.myMethod("this is Dynamic Object");  
162   
163    
164   
165 执行结果:  
166   
167 FirstAttribute  
168   
169 this is Dynamic Object  
DynamicObject(实现自己的可扩展类型)

反射

   反射在日常开发中用的很少,也很难用。我至今也没找到在什么地方使用这项技术会有意想不到的效果。下面贴个小例子,简单了描述下反射。

 1 using System;  
 2   
 3 using System.Collections.Generic;  
 4   
 5 using System.Linq;  
 6   
 7 using System.Text;  
 8   
 9    
10   
11 using System.IO;  
12   
13 using System.Reflection;  
14   
15    
16   
17 namespace chapter14  
18   
19 {  
20   
21     [AttributeUsage(AttributeTargets.All,AllowMultiple=true,Inherited=true)]  
22   
23     public class MemoAttribute:Attribute  
24   
25     {  
26   
27         public MemoAttribute() { }  
28   
29         public string MemoTime { get; set; }  
30   
31         public string MemoContent { get; set; }  
32   
33         public void WriteSomething(string path)   
34   
35         {  
36   
37             File.WriteAllText(path, MemoContent + MemoTime.ToString());  
38   
39         }   
40   
41     }  
42   
43 }  
特性类
  1 using System;  
  2   
  3 using System.Collections.Generic;  
  4   
  5 using System.Linq;  
  6   
  7 using System.Text;  
  8   
  9    
 10   
 11 [assembly: chapter14.Memo(MemoContent = "创建", MemoTime = "2011.11.1")]  
 12   
 13    
 14   
 15 namespace chapter14  
 16   
 17 {  
 18   
 19    
 20   
 21      
 22   
 23     [Memo(MemoContent="创建",MemoTime="2011.11.1")]  
 24   
 25     class Robot  
 26   
 27     {  
 28   
 29    
 30   
 31         public string Name { get; set; }  
 32   
 33         [Memo(MemoContent="修改",MemoTime="2011.11.2")]  
 34   
 35         public string Detail { get; set; }  
 36   
 37    
 38   
 39         [Memo(MemoContent="修改",MemoTime="2011.11.4")]  
 40   
 41         [Memo(MemoContent="修改",MemoTime="2011.11.3")]  
 42   
 43         [Memo(MemoContent="创建",MemoTime="2011.11.1")]  
 44   
 45         public void CreateBomb()  
 46   
 47         {  
 48   
 49             Console.WriteLine("CreateBomb");  
 50   
 51         }  
 52   
 53    
 54   
 55         public void LayBomb()  
 56   
 57         {  
 58   
 59             Console.WriteLine("LayBomb");  
 60   
 61         }  
 62   
 63    
 64   
 65         public void Kill()  
 66   
 67         {  
 68   
 69             Console.WriteLine("Kill");  
 70   
 71         }  
 72   
 73    
 74   
 75         public void Save()  
 76   
 77         {  
 78   
 79             Console.WriteLine("Save");  
 80   
 81         }  
 82   
 83    
 84   
 85         public void Escape()  
 86   
 87         {  
 88   
 89             Console.WriteLine("Escape");  
 90   
 91         }  
 92   
 93    
 94   
 95         public void Kill(string name)  
 96   
 97         {  
 98   
 99             Console.WriteLine(name + " was dead.");  
100   
101         }  
102   
103    
104   
105         public string GetInfomation()  
106   
107         {  
108   
109             return DateTime.Now.ToString();  
110   
111         }  
112   
113     }  
114   
115 }  
调用特性类的类型
//简单的获取在类上定义的“特性类”MemoAttribute           
  
    Type robot = typeof(Robot);  
  
    object[] attributes = robot.GetCustomAttributes(true);  
  
   
  
    foreach (object tmp in attributes)  
  
    {  
  
        MemoAttribute memo = tmp as MemoAttribute;  
  
        if (memo == null)  
  
        {  
  
            continue;  
  
        }  
  
        Console.WriteLine(string.Format("Content:{0},DateTime:{1}", memo.MemoContent, memo.MemoTime));  
  
    }  
  
   
  
执行结果:  
  
Content:创建,DateTime:2011.11.1  
执行代码(获取定义在robot类上的特性标记“[Memo(MemoContent="创建",MemoTime="2011.11.1")]”)
Type robot = typeof(Robot);  
  
    MemberInfo[] members = robot.GetMembers();  
  
    object[] tmp;  
  
    MemoAttribute memo;  
  
   
  
   
  
    foreach (MemberInfo member in members)  
  
    {  
  
        int indent = 0;//添加缩进  
  
        Console.WriteLine(string.Format("Name:{0},Type:{1}", member.Name, member.MemberType));  
  
        indent++;  
  
        tmp = member.GetCustomAttributes(typeof(MemoAttribute), true);  
  
        foreach (object o in tmp)  
  
        {  
  
            memo = o as MemoAttribute;  
  
            if (o == null)  
  
            {  
  
                continue;  
  
            }  
  
            Console.WriteLine(string.Format("{0}content:{1},datetime:{2}", "".PadLeft(indent * 5, ' '), memo.MemoContent, memo.MemoTime));  
  
   
  
        }  
  
   
  
    }  
  
   
  
执行结果:  
  
Name:get_Name,Type:Method  
  
Name:set_Name,Type:Method  
  
Name:get_Detail,Type:Method  
  
Name:set_Detail,Type:Method  
  
Name:CreateBomb,Type:Method  
  
     content:创建,datetime:2011.11.1  
  
     content:修改,datetime:2011.11.4  
  
     content:修改,datetime:2011.11.3  
  
Name:LayBomb,Type:Method  
  
Name:Kill,Type:Method  
  
Name:Save,Type:Method  
  
Name:Escape,Type:Method  
  
Name:Kill,Type:Method  
  
Name:GetInfomation,Type:Method  
  
Name:ToString,Type:Method  
  
Name:Equals,Type:Method  
  
Name:GetHashCode,Type:Method  
  
Name:GetType,Type:Method  
  
Name:.ctor,Type:Constructor  
  
Name:Name,Type:Property  
  
Name:Detail,Type:Property  
  
     content:修改,datetime:2011.11.2  
调用代码(打印出标记在robot类型内的所有MemoAttribute特性类的值:方法,属性等)

通过反射在运行时调用方法

    也就是在程序运行后更具某些情况来决定调用定义在类型上的某个方法,真正的解耦

Type robot = typeof(Robot);  
  
    MemberInfo[] members = robot.GetMembers();  
  
    object[] tmp;  
  
    MemoAttribute memo;  
  
   
  
    //动态调用方法   插件编程  
  
    foreach (MemberInfo member in members)  
  
    {  
  
   if (member.MemberType == MemberTypes.Method && member.Name.ToLower()  
  
                           =="createbomb")  
  
     {  
  
        //构造函数  
  
        object tmpRobot = robot.InvokeMember(null, BindingFlags.DeclaredOnly |  
  
                                                         BindingFlags.Public |  
  
                                                      BindingFlags.NonPublic |  
  
                                                       BindingFlags.Instance |  
  
                                                  BindingFlags.CreateInstance  
  
, null, null, null);  
  
   
  
       robot.InvokeMember("CreateBomb", BindingFlags.InvokeMethod  
  
, null, tmpRobot, null);  
  
       robot.InvokeMember("Kill", BindingFlags.InvokeMethod  
  
, null, tmpRobot, new object[] { "秦萱" });  
  
       Console.WriteLine((string)robot.InvokeMember("GetInfomation",  
  
                              BindingFlags.InvokeMethod, null, tmpRobot, null));  
  
        }  
  
   
  
    }  
  
   
  
执行结果:  
  
CreateBomb  
  
秦萱 was dead.  
  
2012/2/23 20:03:55  

 

应用在程序集上的反射

    这个例子获取的是定义在程序集“robot”上的MemoAttribute特性。

//加载程序集  
  
    Assembly chapter14 = Assembly.GetAssembly(typeof(Robot));  
  
    object[] attributes = chapter14.GetCustomAttributes(typeof(MemoAttribute), true);  
  
    MemoAttribute memo;  
  
   
  
    foreach (object attribute in attributes)  
  
    {  
  
        memo = attribute as MemoAttribute;  
  
        if (memo == null)  
  
        {  
  
            continue;  
  
        }  
  
        Console.WriteLine(string.Format("Content:{0},DateTime:{1}", memo.MemoContent, memo.MemoTime));  
  
    }  
  
   
  
    Console.WriteLine();  
  
   
  
    Console.ReadKey();  
  
   
  
执行结果:  
  
Content:创建,DateTime:2011.11.1  

 

posted @ 2017-08-25 10:38  多加些蜂蜜  阅读(1205)  评论(0编辑  收藏  举报