|
|
置顶随笔
摘要: 有没有觉得干了一段时间以后工作很不开心?有没有觉得自己入错了行?有没有觉得自己没有得到应有的待遇?有没有觉的工作像一团乱麻每天上班都是一种痛苦? 有没有很想换个工作?有没有觉的其实现在的公司并没有当初想象的那么好?有没有觉的这份工作是当初因为生存压力而找的,实在不适合自己?你从工作中得到你 想要得到的了吗?你每天开心么?分愤怒的人很多,你有没有想过,你为什么不快乐?你为什么愤怒? 其实,你不快乐的... 阅读全文
摘要: 用户在ASP.NET应用程序显示的页面上面点击一个Button、LinkButton、或者改变某个TextBox的Value时(启用AotuPostBack),就会导致页面提交,并且在服务器端引发对应的PostBack事件,大家可以想象客户端浏览器显示的是html,而html是不存在引发PostBack事件这一说的,这样就说明ASP.NET应用程序肯定提供一种方法,能够知道用户在客户端做了什么动作... 阅读全文
2009年2月20日
有没有觉得干了一段时间以后工作很不开心?有没有觉得自己入错了行?有没有觉得自己没有得到应有的待遇?有没有觉的工作像一团乱麻每天上班都是一种痛苦? 有没有很想换个工作?有没有觉的其实现在的公司并没有当初想象的那么好?有没有觉的这份工作是当初因为生存压力而找的,实在不适合自己?你从工作中得到你 想要得到的了吗?你每天开心么?分愤怒的人很多,你有没有想过,你为什么不快乐?你为什么愤怒?
其实,你不快乐的根源,是因为你不知道要什么!你不知道要什么,所以你不知道去追求什么, 你不知道追求什么,所以你什么也得不到.
我总觉得职业生涯首先要关注的是自己,自己想要什么?大多数人大概没想过这个问题,唯一的想法只是--我想要一份工作,我想要一份不错的薪水, 我知道所有人对于薪水的渴望,可是,你想每隔几年重来一次找工作的过程么?你想每年都在这种对于工作和薪水的焦急不安中度过么?不想的话,就好好像清楚.饮鸠止渴,不能因为口渴就拼命喝毒药.越是焦急,越是觉得自己需要一份工作,约饥不择食,越想不清楚,越容易失败,你的经历越来越差.于是你越喝越渴,越渴越喝,陷入恶性循环.最终只能哀叹世事不公或者生不逢时,只能去天涯上面发泄一把,在失败者的共鸣中需求一点心理平衡罢了。大多数人都有生存的压力,我也是,有生存压力就会有很多焦虑,积极的人会从焦虑中得到动力,而消极的人则会因为焦虑而迷失方向.所以人都必须在压力下做出选择,这就是世道,你喜欢也罢不喜欢也罢.
一般我们处理的事情分为重要的事情和紧急的事情,如果不做重要的事情就会常常去做紧急的事情.比如锻炼身体保持健康是重要的事情,而看病则是紧急的事情. 如果不锻炼身体保持健康,就会常常为了痛苦烦恼.又比如防火是重要的事情,而救火是紧急的事情,如果不注意防火,就要常常救火.找工作也是如此,想好自己 究竟要什么是重要的事,找工作是紧急的事情,如果不想好,就会常常要找工作.往往紧急的事情给人的压力比较大,迫使人们去赶紧做,相对来说重要的事情反而 没有那么大的压力,大多数人做事情都是以压力为导向的,压力之下,总觉得非要先做紧急的事情.结果就是永远到处救火,永远没有停歇的时候.(很多人的工作 也像是救火队一样的忙碌痛苦,也是因为工作中没有做好重要的事情),那些说自己活在水深火热为了生存顾不上那么多的朋友,今天找工作困难是当初你们没有做 重要的事情,是结果不是原因。如果今天你们还是因为急于要找一份工作而不去思考,那么或许将来要继续承受痛苦找工作的结果.
话题貌似沉重了点,需要很多思考,远比唐笑打武警的话题来的枯燥乏味,但是,天下没有轻松的武功,成功要付代价.请先忘记一切的生存压力,想想这辈子你最想要的是什么?所以最要的事情,先想好自己想什么.
这是我们公司月周刊上面的一篇文章,我见得受益匪浅,因此分享给园友门.
2008年11月3日
用户在ASP.NET应用程序显示的页面上面点击一个Button、LinkButton、或者改变某个TextBox的Value时(启用AotuPostBack),就会导致页面提交,并且在服务器端引发对应的PostBack事件,大家可以想象客户端浏览器显示的是html,而html是不存在引发PostBack事件这一说的,这样就说明ASP.NET应用程序肯定提供一种方法,能够知道用户在客户端做了什么动作导致页面被提交的,然后服务器端根据这个信息引发相应的服务器端控件的PostBack事件,那么这篇文章,我们一起来讨论下ASP.NET应用程序是如何来引发PostBack事件.
首先我们通过最直接的方式来查看ASP.NET Page 根据什么信息来引发对应控件的PostBack事件的,我们知道 页面继承与 Page类,服务器端接受到一个页面请求时,服务器端会按预期的进行一系列的处理,这个就是Page 页面的生命周期,在这里我们就不讨论这个内容的,因为已经有很多文章介绍Page生命周期的内容的,这里我们只关注Page类型中RaisePostBackEvent方法里面的逻辑,我们通过Reflector查看 Page类型的RaisePostBackEvent方法.
private void RaisePostBackEvent (NameValueCollection postData)
{
if (this._registeredControlThatRequireRaiseEvent != null)
{
this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
}
else
{
string str = postData["__EVENTTARGET"];
bool flag = !string.IsNullOrEmpty(str);
if (flag || (this.AutoPostBackControl != null))
{
Control control = null;
if (flag)
{
control = this.FindControl(str);
}
if ((control != null) && (control.PostBackEventHandler != null))
{
string eventArgument = postData["__EVENTARGUMENT"];
this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);
}
}
else
{
this.Validate();
}
}
}
这段代码做这样几件事情,首先判断是否页面上有某个控件注册引发PostBack事件,通常通过Page.RegisterRequiresPostBack(Control control)方法来注册的,如果没有控件注册引发PostBack事件,那么就会查看回传页面的post数据中是否包含这样2个键值对,__EVENTTARGET 和 __EVENTARGUMENT,如果__EVENTTARGET键包含值,那么通过Page.FindControl找到控件的引用并查看该控件PostBackEventHandler是否为空,不为空那么就引发这个控件的PostBackEvent,这个就是ASP.NET如何引发页面回传事件的逻辑啦.
对于第一种方式在服务器端为某个控件注册需要引发回传事件,这通常是在我们开发的完全定制自定义控件中需要使用的(完全定制也就是不组合已有的服务器端控件),通过在自定义的控件中实现IPostBackEventHandler 和 IPostBackDataHandler 接口, IPostBackDataHandler接口需实现2个方法 bool LoadPostData(string postDataKey, NameValueCollection postCollection) 和 void RaisePostDataChangedEvent().我们需要在LoadPostData 方法中判断回发数据是否包含你想要的信息(页面提交会将form中的信息以key-value的形式提交到服务器,在这里我们只需要判断key-value集合中是否包含对应控件的Name属性即可),如果包含我们想要的信息,那么就说明是我们自定义的控件引发的回传,这样则可将这个控件注册为需要引发回传事件.
对于第二种方式,比如像LinkButton控件,其呈现时生成的Html代码不是<input type="submit"/>,因此他本身是不具备提交页面的功能,因此客户端必须通过JavaScript来实现页面提交,但是由于LinkButton呈现的html代码是<a>标签,页面提交时并不会将<a>标签key-value进行打包,所以页面提交后,服务器端无法找到到底是谁引发的页面回传,因此ASP.NET提供2个Hidden Input标签.
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
这2个东东相信大家经常看到,当你点击LinkButton时,客户端会通过JavaScript将被点击的LinkButton的Name和对应的参数存储在这2个hidden input中,然后提交页面,页面会将这2个hidden input 打包,以key-value的形式传回到服务器端,服务器端就可以通过 postData["__EVENTTARGET"] 来获取究竟是什么引发页面回传,进而找到其对应的服务端控件并触发其回传事件.
以上就是Web Form引发回发事件的内幕啦,本开始准备写几个例子来一一讲述,便于与大家交流,但是写个简单自定义控件要敲蛮多代码,本人比较懒,所以只好全部用文字来讲述啦,如果有表达不清楚的地方,请见谅.
2008年7月3日
在C#中,相信大家对于 "值类型" 并不陌生,因为它在我们代码设计中是不可缺少的,那么究竟什么是 "值类型" 呢? "值类型" 就是 我们用到的 Int16,Int32这些数值类型吗?
我们知道在C#中所有的类型继承于System.Object根类型,这也就意味着就代码层面来讲,在C#中所有的类型都是Class,,即一切都是Class类型,既然全部都是Class类型,那么值类型在哪里呢?我们可以发现在C#中System.Int16,System.Int32,System.Boolean...等等这些常用的类型都是Struct 结构类型,那么结构类型是什么,下面我们定义一个结构,然后通过IL Disassemble 工具来查看编译的中间代码便可以得到结果.
1 public struct CustomerStruct
2 {
3 public string Name { get; set; }
4 }
代码非常简单,我们就定义一个struct类型,并且包含一个Name属性.

看到上面这幅图,相信大家都已经看到定义一个struct类型实际上编译把你所定义的类型继承了System.ValueType类型,换句话说,在C#中我们经常使用的System.Int16,System.Int32,System.Boolean..这些数值结构类型都是继承于System.ValueType类型,而System.ValueType又是继承于System.Object根类型,即验证我开始所讲到的在C#中一切类型都是Class。
之所以存在"值类型" 这个概念,其实是因为C#中的某些类型有这特殊的地位(即继承于System.ValueType的类型),CLR会特殊的对待这些类型,
看下面这2行代码
Int32 a = new System.Int32(10) ;

CustomerStruct customer = new CustomerStruct() ;
首先为什么对于数值类型也可以使用 new 来进行内存分配呢? 上面已经讲到,因为他们都是Class类型,当然可以使用new 来进行内存分配.
其次,CLR执行这样的代码的时,CLR 通过反射(有待考察)或者其他途径来获知所要请求分配内存的类型是否继承于System.ValueType如果是的话,那么就在栈上进行分配,如果不是的话,那么就是我们所说的引用类型,就在托管堆上分配内存以及栈上分配对应的引用变量,这些一切都是CLR做的工作.
我们再来看看装箱操作.
object o = new object();
Int32 aaa = 100;
o = aaa; //这里会发生装箱操作
我们都知道当CLR执行到 o = aaa;这条语句时会发生装箱操作,为什么会发生装箱操作呢?这是因为CLR 知道引用变量o所要引用的类型aaa是继承于System.ValueType类型的,继承于System.ValueType的类型都是在栈上分配的,而其它则是在托管堆上分配的,所以会CLR会弄得aaa的副本弄到托管堆上去,这一切也都是CLR的工作.
由此我们可以得出结论: 1.在C#中 就代码层面上讲 所有的类型都是Class类型.
2.所谓的 "值类型" != 数值类型,而是所有继承于System.ValueType 的类型.
3."值类型" 得到的语言级别的支持,CLR知道如何对 "值类型" 这样的Class类型进行内存分配和处理.
|