LINQ查询表达式以from子句开始,以select或者group子句结束。在这两个子句之间能够跟零个或者多个from、let、where、join或者orderby子句。html
static void LINQQuery() { //Formula1.GetChampions()返回一个列表,quer变量只是一个赋值语句,只有使用了foreach才会执行查询 var query = from r in Formula1.GetChampions() where r.Country == "Brazil" orderby r.Wins descending select r; foreach (var r in query) { Console.WriteLine("{0:A}", r); } }
11.1.3扩展方法python
若是有类的源码,继承就能够给对象添加方法。但若是没有源代码,则可使用扩展方法,它容许改变一个类,但不须要该类的源代码。
扩展方法是静态方法,它是类的一部分,但实际上没有放在类的源代码中。假定PhoneCusStruct类须要一个Add()方法,但不能修改源代码,就能够建立一个静态类,把Add()方法添加为一个静态方法算法
public static class PhoneExtension { public static void Add(this PhoneCusStruct phoneCusStruct,string phone) { // }
注意扩展方法的第一个参数是要扩展的类型,它放在this关键字的后面。这告诉编译器,这个方法是PhoneCusStruct类型的一部分。在这个例子中,PhoneCusStruct是要扩展的类型。在扩展方法中,能够访问所扩展类型的全部公有方法和属性。
调用:PhoneCusStruct p =new PhoneCusStruct();
p.Add();//即便方法是静态方法,也须要使用实例方法的语法。
若是扩展方法与类中的某个方法同名,就不会调用扩展方法。类中已有的任何实例方法优先。数据库
编译器会转换LINQ查询,以调用方法而不是LINQ查询。LINQ为IEnumerable<T>接口提供了各类扩展方法(扩展方法在上面介绍到),以便用户在实现了该接口的任意集合上使用LINQ查询。
定义LINQ扩展方法的一个类是System.Linq名称空间中的IEnumerable。只须要导入这个名称空间,就打开了这个类的扩展方法的做用域。下面是Where()扩展方法的实现代码:编程
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate) { foreach(TSource item in source) { if(predicate(item)) { yield return item; } } }
由于Where()做为一个泛型方法,因此它能够用于包含在集合中的任意类型。实现了IEnumerable<T>接口的任意集合都支持它。安全
相关连接框架
其因相关使用在应用环境中再学习!这里先作了解异步
Dynamic Language Runtime动态语言容许添加动态语言,如Ruby和Python.async
dynamic的对象能够在运行期间改变其类型.其类型是有用的,但它是有代价的!异步编程
dynamic dyn; dyn = 100; Console.WriteLine(dyn.GetType()); //输出System.int32 Console.WriteLine(dyn); //输出100 dyn = "This is a string"; Console.WriteLine(dyn.GetType()); //输出System.String Console.WriteLine(dyn); //输出This is a string
利用脚本完成工做,相关应用相对少,可请选读 因要了解python语言,暂时跳过
13.1
一、Invoke() 调用时,Invoke会阻止当前主线程的运行,等到 Invoke() 方法返回才继续执行后面的代码,表现出“同步”的概念。
二、BeginInvoke() 调用时,当前线程会启用线程池中的某个线程来执行此方法,BeginInvoke不会阻止当前主线程的运行,而是等当前主线程作完事情以后再执行BeginInvoke中的代码内容,表现出“异步”的概念。
IAsyncResult rtn = 委托变量.BeginInvoke(……); // 启动异步调用
三、EndInvoke() ,在想获取 BeginInvoke() 执行完毕后的结果时,调用此方法来获取。
用于保存方法结果的变量=委托变量.EndInvoke(rtn); // 阻塞并等待异步调用结束
static string Greeting(string name) //Greeting同步方法 { Console.WriteLine("运行时访问的线程是:{0}与任务是:{1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); Thread.Sleep(3000); return string.Format("Hello, {0}", name); } static Task<string> GreetingAsync(string name) //异步方法GreetingAsync返回的是Task<string> { return Task.Run<string>(()=> { return Greeting(name);
Console.WriteLine("running greetingasync in thread {0} and task {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
});
}
private async static void CallerWithAsync() { Console.WriteLine((await GreetingAsync("Stephanie")); //async修饰符只能用于返回Task或Void的方法 }
ContinueWith方法定义了任务完成后就调用的代码(注:如任务清理工做可等)
private static void CallerWithContinuationTask() { Console.WriteLine("CallerWithContinuationTask线程为 {0} 任务 {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); var t1 = GreetingAsync("Stephanie"); t1.ContinueWith(t => { string result = t.Result; // 访问任务返回的结果 Console.WriteLine(result); Console.WriteLine("完成后的运行线程 {0} 任务 {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); }); } //输出为: // CallerWithContinuationTask线程为 1 任务 // running greetingasync in thread 3 and task 1 // 运行时访问的线程是:3与任务是:1 // Hello, Stephanie // 完成后的运行线程 4 任务 2
上下文简单理解为当时的环境便可,环境能够包括当时程序状态以及变量的状态,例如线程切换的时候在内核会发生上下文切换,这里的上下文就包括了当时寄存器的值,把寄存器的值都保存起来,等下次该线程又获得CPU时间的时候再恢复寄存器的值,这样线程才能正确的运行.
//若是不加上下文,那么就是以对象为线程锁定区域,若是加上下文,那么就是以逻辑上下文为锁定区域 [Synchronization(SynchronizationAttribute.REQUIRED, true)] class synchronizationClass : ContextBoundObject { public void Start() { MessageBox.Show(Thread.CurrentThread.Name); } }
由于是使用SynchronizationAttribute来建立锁的,因此第一句[Synchronization(SynchronizationAttribute.REQUIRED, true)] 是必不可少的。
又由于是为ContextBoundObject对象建立锁,因此对象必须是ContextBoundObject,故必须继承ContextBoundObject。
二者缺一不可。测试:
synchronizationClass myclass = new synchronizationClass(); Thread thread = new Thread(new ThreadStart(myclass.Start)); thread.Name = "thread1";
Thread thread2 = new Thread(new ThreadStart(myclass.Start)); thread2.Name = "thread2"; thread.Start(); thread2.Start();
现象是thread1先弹框,点击肯定后再弹thread2,缘由就是整个对象都是一个锁,就是在thread1没处理完,thread2是没法进行操做的。
因此呢,上下文同步域会将整一个上下文所有锁定,就是说整个类都成为了一个锁,在线程1未走出该类,线程2就没法进入该类。
加入我把[Synchronization(SynchronizationAttribute.REQUIRED, true)]或者不继承ContextBoundObject发现此时的现象是thread1和thread2都会弹出框。
这就是锁与不锁的区别了。
1.按顺序调用异步方法 (按顺序使用await)
2.使用组合器
Task<string> t1 = GreetingAsync("Stephanie");await Task.WhenAll(t1, t2);//全部提供的任务都已完成时,才会返回Tack
Task.WhenAny()//在其中一个任何提供的任务已完成时,就会返回Tack
转换为基于任务的异步模式 基于任务模式的异步的相关知识点
private static async void ConvertingAsyncPattern() { string r = await Task<string>.Factory.FromAsync<string>(BeginGreeting, EndGreeting, "Angela", null);//建立一个任务,它表示符合异步编程模型模式的成对的开始和结束方法。 Console.WriteLine(r); } /// <summary> /// 从同步方法中借助委拖,建立一个异步方法 /// </summary> private static Func<string, string> greetingInvoker = Greeting; /// <summary> /// 异步模式 /// </summary> /// <param name="name">异步模式名</param> /// <param name="callback">异步操做的状态</param> /// <param name="state"></param> /// <returns></returns> static IAsyncResult BeginGreeting(string name, AsyncCallback callback, object state) { return greetingInvoker.BeginInvoke(name, callback, state); } static string EndGreeting(IAsyncResult ar) { return greetingInvoker.EndInvoke(ar); }
static async Task ThrowAfter(int ms, string message) { await Task.Delay(ms); throw new Exception(message); } private static async void HandleOneError() { try { await ThrowAfter(2000, "first");//若是不加入await的话 就没法捕捉异常! } catch (Exception ex) { Console.WriteLine("handled {0}", ex.Message); } }
Task taskResult = null; try { Task t1 = ThrowAfter(2000, "first"); Task t2 = ThrowAfter(1000, "second"); await (taskResult = Task.WhenAll(t1, t2)); } catch (Exception ex) { // 第一个任务的异常信息,只显示在全部等待 Console.WriteLine("handled {0}", ex.Message); foreach (var ex1 in taskResult.Exception.InnerExceptions) { Console.WriteLine("inner exception {0} from task {1}", ex1.Message, ex1.Source); } }
private CancellationTokenSource cts = new CancellationTokenSource(); private void OnCancel(object sender, RoutedEventArgs e) { if (cts != null) cts.Cancel(); }
private async void OnTaskBasedAsyncPattern(object sender,RoutedEventArgs e) { cts =new CancellationTokenSourcs(); try{ foreach(var req in GetSearchRequests()) var Client =new HttpClient(); var response = await Client.GetAsync(req.Url, cts.Token);//用以异步操做的 HTTP 完成选项和取消标记发送 GET 请求到指定的 URI。 string resp = await Response.Content.ReadAsStringAsync(); } catch (OperationCanceledException ex) { MessageBox.Show(ex.Message); } }
13.5.3取消自定义任务
没测试!!跳过
private async void test() { await Task.Run(() => { var images = req.Parse(resp); foreach(var image in images) { cts.Token.ThrowIfCancellationRequested(); searchInfo.list.add(image); } }, cts.Token); }
int类型为为4个字节,即占用4个指针位. double占8个字节
参考C的示例
#include<stdio.h> int *fun1(){ int a; return &a;} int fun2(){ int b=6; } int main(){ int *p=fun1(); fun2(); printf("%d\n",*p);}
局部变量在函数调用完就会擦除(应该跟程序的联系),但是你使用局部变量时存放的是栈段,栈段的顺序是后进先出,而你恰好申请了相同大小的变量空间,系统直接就把那块空间又分配给你了,而里面的内容并没擦除。
托管程序会自动更新地址,压缩堆造成一个链接的内存块
GC是一个垃圾回收机制 它主要是回收 托管对象 而不会回收 非托管对象 就像你使用某些非托管数据库连接对象的时候 就须要手动关闭 这些须要手动关闭的对象就是非托管对象 而这个就不是在GC管理范围以内
另外要说一下的是 GC这个东西很调皮 有时候GC的回收是没有固定时间的 随机的 因此 有时候咱们须要手动关闭一些比较大的托管对象来提升性能
14.3.2IDisposable接口
在C#中,推荐使用System.IDisposable接口替代折构函数
class ResouerceGobbler : IDisposable { public void Dispose() { } }
ResouerceGobbler theInstance = new ResouerceGobbler(); //使用
//程序
theInstance.Dispose() //释放
若是处理过程当中出现异常,没有释放,因此应该使用
ResouerceGobbler theInstance = null; try { theInstance = new ResouerceGobbler(); //程序
} finally { if (theInstance != null) { theInstance.Dispose(); } }
以上代码有点混乱,因此有了下面的语法
using( ResouerceGobbler theInstance = new ResouerceGobbler()) { //程序 }
close()是调用dispose()的方法实现的
使用指针的主要缘由
1.向后兼容性
调用本地WindowsAPI函数,可使用DllLmport声明,以免使用指针
2.性能
unasfe int GetSomeNumber(){} //表示这是一个不安全的方法! 也能够标记class或参数虚方法等,不能在局部变量自己标记为unsafe
若是要使用不安全变量,须要在不安全的方法中声明和使用它
VS可在项目属性窗口的Build选项中找到不安全代码的选项
二.指针的语法(命名时前面是小写p)
int* pWidth; //*是在类型后面!!与变量无关 C++中是在变量上 如: int *pWidth ,要区分开
&表示取地址 int* pX =&x //表示pX指向x
3将指针强制转换为整数类型
int x=10; int* pX,pY; pX = &x; pY =pX; * pY =20; uint y =(uint)pX; int* pD = (int*) Y;
4.指针类型之间的强制转换
double* pDouble = (double*) pByte//pByte指针转换为double指针,不会获得一个有意义的值. (合法的代码)
5.void指针
int* pointerToInt; void* pointerToVoid; pointerToVoid = (void*)pointerToInt;//不多用,主要用于调用须要void*参数API函数
6.指针算术的运算 +、-、+=、-=、++、--
int* pInt=&int变量; pInt += 1 //不容许对void指针运算,注意byte与char其总字节数不是4的倍数,不能使用P+X*(sizeof(T))算法
7sizeof运算符
int x =sizeof(double) //返double类型占用的字节数,注意不能用于计算类
8.结构指针:指针成员访问运算符
struct MyStruct {public log X; public float F; } MyStruct* pStruct; //定义一个指针 MyStruct Struct = new MyStruct(); //初始化 pStruct = &Struct; //经过指针访问结构成员 (*pStruct).X = 4; (*pStruct).Y =3.4f;
上述代码改写为
pStruct->X = 4; pStruct->Y = 3.4f;
类成员指针
对象存储在堆上,垃圾回收过程会变更,因此要使用fixed,语法以下
MyClass myObject =new MyClass(); Fixed (long* pX = &(myObject.X)) Fixed (float* pF = &(myObject.F)) { //程序 }
//类型相同时能够放在一条fixed中 fixed(long* pX = &(myObject.X),pF = &(myObject.F))若是不一样阶段固定指针,能够嵌套fixed块
14.4指针示例
使用{0:X}格式输出十六进制
下面为自定义元素时
[FieldNameAttribute("SocialSecurityNumber")] public string SocialSecurityNumber { get{ //ect
一、AttributeUsage特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] //AllowMultiple = true 容许它屡次应用到同一项上
//Inherited = false若是该属性能够由派生类和重写成员继承,则为 true;不然为 false。 默认值为 true public class LastModifiedAttribute : Attribute { public LastModifiedAttribute(string dateModified, string changes) { //程序 } }
[LastModified("14 Feb 2010", "IEnumerable interface implemented So Vector can now be treated as a collection")]
属性
Type intType=typeof(int); //Type的属性 name, fullname, Namepace命名空间, BaseType基类型 isClass是否为类
方法
Type intType = typeof(int); MethodInfo[] methods = intType.GetMethods(); //取得该类型的法方 foreach (var test in methods) { Console.WriteLine(test); }
加载
Assembly theAssembly = Assembly.Load("VectorClass"); //查找程序集"VectorClass" Assembly theAssembly = Assembly.LoadFrom(@"c:\12\Some"); //在c:\12\Some查找程序集"VectorClass"
1,获取程序集中定义的类型的详细信息
ype[] types = theAssembly.GetTypes();
2获取自定义特性的详细信息
Attribute supportsAttribute = Attribute.GetCustomAttribute(theAssembly, typeof (SupportsWhatsNewAttribute)); //获取程序集的特性
关于使用
Type T2 = typeof(TClass); var Mets = T2.GetMembers();//获取全部公共成员(返回值是MemberInfo类型集合) foreach (var m in Mets) { if (m.Name=="Equals") { Console.WriteLine("【" + m.MemberType.ToString() + "】:" + m.Name); // m.MemberType 是成员类型 // m.DeclaringType;//获取申明该成员的类 // m.ReflectedType;//获取用于获取 MemberInfo 的此实例的类对象。 } }
try { throw new Exception("ft"); } catch (OverflowException ex) { } catch (Exception ex) { } finally {
//程序完成后必定会执行的操做
}