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(""));
}
执行结果:
you want to print the data:
委托数组
class Program
{
//定义委托数组
public delegate void BlukPrintSomething();
static void Main(string[] args)
{
//委托数组
BlukPrintSomething[] bluckPrintSomething = new BlukPrintSomething[]{
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("", "", "", "");
}
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("", "", "", "");
}
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 // ::
this event is trigger on // ::
this event is trigger on // ::
this event is trigger on // ::
this event is trigger on // ::
事件
动态语言(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 = ;
Console.WriteLine(data2);
data2 = new Object();
Console.WriteLine(data2);
执行结果:
this is a string
this is a string
this is a string
System.Object
ExpandoObject(扩展对象)
这个类型的对象与JavaScript中的变量类似,可以动态的扩展。
dynamic data = new ExpandoObject();
data.FirstAttribute = "FirstAttribute";
data.SecondAttribute = "SecondAttribute";
data.ThirdAttribute = "ThirdAttribute";
ArrayList nums = new ArrayList();
for (int i = ; i <= ; 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.");
}
执行结果:
FirstAttribute
SecondAttribute
ThirdAttribute
This is dynamic method.
Go!Go!Fighting!
扩展对象
DynamicObject(实现自己的可扩展类型)
自己也可以实现扩展类型,但没有系统自带的扩展类型(ExpandoObject)好用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
namespace chapter12
{
class MyDynamicObject:DynamicObject
{
Dictionary<string, object> data = new Dictionary<string, object>();
/// <summary>
///
/// </summary>
/// <param name="binder">传进来的参数,包含了调用信息</param>
/// <param name="result">返回包含的对象</param>
/// <returns>返回是否成功</returns>
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
bool isContain = false;
if (data.ContainsKey(binder.Name))
{
result = data[binder.Name];
isContain = true;
}
else
{
result = "Not Find";
}
return isContain;
}
/// <summary>
///
/// </summary>
/// <param name="binder">传进来的参数,包含了调用信息</param>
/// <param name="value">传进来的参数,包含了调用信息</param>
/// <returns></returns>
public override bool TrySetMember(SetMemberBinder binder, object value)
{
bool result = false;
if (!data.ContainsKey(binder.Name))
{
data[binder.Name] = value;
result = true;
}
return result;
}
/// <summary>
///
/// </summary>
/// <param name="binder">传进来的参数,包含了调用信息</param>
/// <param name="args">传进来的参数,包含了调用信息</param>
/// <param name="result">方法体执行后返回的结果</param>
/// <returns>调用是否成功</returns>
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic tmp = data[binder.Name];
result = null;
tmp((string)args[]);
return true;
}
}
}
调用代码:
dynamic myDynamicObject = new MyDynamicObject();
myDynamicObject.FirstAttribute = "FirstAttribute";
Action<string> myMethod = a => Console.WriteLine(a);
myDynamicObject.myMethod = myMethod;
Console.WriteLine(myDynamicObject.FirstAttribute);
myDynamicObject.myMethod("this is Dynamic Object");
执行结果:
FirstAttribute
this is Dynamic Object
DynamicObject(实现自己的可扩展类型)
反射
反射在日常开发中用的很少,也很难用。我至今也没找到在什么地方使用这项技术会有意想不到的效果。下面贴个小例子,简单了描述下反射。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace chapter14
{
[AttributeUsage(AttributeTargets.All,AllowMultiple=true,Inherited=true)]
public class MemoAttribute:Attribute
{
public MemoAttribute() { }
public string MemoTime { get; set; }
public string MemoContent { get; set; }
public void WriteSomething(string path)
{
File.WriteAllText(path, MemoContent + MemoTime.ToString());
}
}
}
特性类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
[assembly: chapter14.Memo(MemoContent = "创建", MemoTime = "2011.11.1")]
namespace chapter14
{
[Memo(MemoContent="创建",MemoTime="2011.11.1")]
class Robot
{
public string Name { get; set; }
[Memo(MemoContent="修改",MemoTime="2011.11.2")]
public string Detail { get; set; }
[Memo(MemoContent="修改",MemoTime="2011.11.4")]
[Memo(MemoContent="修改",MemoTime="2011.11.3")]
[Memo(MemoContent="创建",MemoTime="2011.11.1")]
public void CreateBomb()
{
Console.WriteLine("CreateBomb");
}
public void LayBomb()
{
Console.WriteLine("LayBomb");
}
public void Kill()
{
Console.WriteLine("Kill");
}
public void Save()
{
Console.WriteLine("Save");
}
public void Escape()
{
Console.WriteLine("Escape");
}
public void Kill(string name)
{
Console.WriteLine(name + " was dead.");
}
public string GetInfomation()
{
return DateTime.Now.ToString();
}
}
}
调用特性类的类型
//简单的获取在类上定义的“特性类”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.
执行代码(获取定义在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 = ;//添加缩进
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 * , ' '), 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.
content:修改,datetime:2011.11.
content:修改,datetime:2011.11.
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.
调用代码(打印出标记在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.
// ::
应用在程序集上的反射
这个例子获取的是定义在程序集“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.
C#高级语法的更多相关文章
- tn文本分析语言(三):高级语法
标签(空格分隔): 未分类 高级操作 1.脚本表达式 用双引号包含的脚本被称为脚本表达式,目前支持嵌入Python. 脚本表达式只能在顺序表达式中使用.代码可以在三个位置存在: |位置|功能|例子| ...
- Swift高级语法学习总结(转)
Swift高级语法学习总结 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参 ...
- CSS 高级语法 ---- 继承和选择器的分组
1. 选择器的分组 ————————————————————————— 可以对选择器进行分组,被分组的选择器享用共同的声明. h1,h2,h3,h4,h5,h6 { color: green; ...
- Swift高级语法学习总结
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如 ...
- C++ 高级语法学习与总结(代码实例)
C++11增加了许多的特性,auto就是一个很明显的例子. 还有就是typedid()获取数据变量的类型 看下面简短的代码: atuo: 很像java中的加强for循环..... //获取一个数据 ...
- Python自动化 【第七篇】:Python基础-面向对象高级语法、异常处理、Scoket开发基础
本节内容: 1. 面向对象高级语法部分 1.1 静态方法.类方法.属性方法 1.2 类的特殊方法 1.3 反射 2. 异常处理 3. Socket开发基础 1. ...
- iOS开发——语法篇OC篇&高级语法精讲二
Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和 ...
- iOS开发——语法篇OC篇&高级语法精讲
高级语法精讲 一.NSSet.NSMutableSet集合的介绍 1)NSSet.NSMutableSet集合,元素是无序的,不能有重复的值. 2)用实例方法创建一个不可变集合对象 例如: //宏定义 ...
- iOS开发——OC篇&OC高级语法
iOS开发高级语法之分类,拓展,协议,代码块详解 一:分类 什么是分类Category? 分类就是类的补充和扩展部分 补充和扩展的每个部分就是分类 分类本质上是类的一部分 分类的定义 分类也是以代码的 ...
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
随机推荐
- MySQL当月汇总 及负毛利汇总_20161027
#当月汇总 及负毛利汇总 SELECT e.ID,e.city AS 城市 ,f.当月销售总额,f.当月成本总额,f.当月毛利总额,f.当月优惠券总额,f.当月赠品总额,f.当月毛利总额-f.当月优惠 ...
- ACM学习历程—HDU5418 Victor and World(动态规划 && 状压)
这个题目由于只有16个城市,很容易想到去用状压来保存状态. p[i][state]表示到i城市经过state状态的城市的最优值(state的二进制位每一位为1表示经过了该城市,否则没经过) 这样p[j ...
- ACM学习历程—HDU4717 The Moving Points(模拟退火 || 三分法)
Description There are N points in total. Every point moves in certain direction and certain speed. W ...
- 3170: [Tjoi 2013]松鼠聚会
题目大意 给定n个点,找到一个点使这个点到其他所有点的切比雪夫距离之和最小. 题解 我们知道切比雪夫距离和曼哈顿距离的转化公式 \(1\)表示切比雪夫距离,\(2\)表示曼哈顿距离 我们有: \(x_ ...
- forEach、for in 和for of的区别
forEach 不能使用break return 结束并退出循环 for in 和 for of 可以使用break return: for in遍历的是数组的索引(即键名),而for of遍历的是 ...
- 【转】Pro Android学习笔记(五):了解Content Provider(上)
Content Provider是抽象数据封装和数据访问机制,例如SQLite是Android设备带有的数据源,可以封装到一个content provider中.要通过content provider ...
- docker 学习(七) docker 容器挂载
1:docker的默认存放位置: $ sudo su # cd /var/lib/docker # ls -F containers/ graph/ repositories volumes/ ...
- Pointer 指针
利用指针访问对象,指针指向一个对象,允许使用解引用符(操作符*)来访问对象 int ival = 42; int *p = &ival;//p存放变量ival的内存地址,p是指向变量ival的 ...
- win+apache网站打开很慢的解决笔记
为了图方便,直接把wamp的vhost配置文件复制到新apache2.2.25上,结果打开静态页速度都非常慢. <VirtualHost *:> ServerAdmin www.fuck2 ...
- 条款39:明智而审慎的使用private继承
Use private inheritance judiciously. 如果classes之间的继承关系是private,编译器不会自动将一个derived class对象转换为一个base cla ...