ESON

 

2010年5月14日

C#.NET的Linq查询、lambda、委托:Func<>和Action

  这两天在家休息,就研究了下现在比较流行的Linq查询,以及lambda表达式和Func委托与Action委托,做了一些基础的测试,下面贴出代码,如有错误疏忽之处,请指出。

 

代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class LinqSelect : System.Web.UI.Page
{

public static int times = 0;

/*
*Linq查询,从一般的集合中检索一定的数据,一般可分为查询执行和立即执行,下面分别做一些解释:
*查询执行:按照相关说法,Linq查询在定义的时候并不会检索集合中的数据,即定义一个Linq查询而不去遍历这个结果集的话,Linq查询的检索操作将不会被执行;
*立即执行:即定义了Linq查询后就执行,这种定义需要将Linq查询转换为ToArray()或者ToList();
*
*官方说法:在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。
*官方地址:
http://msdn.microsoft.com/zh-cn/library/bb397906.aspx 官方网址对上面二者进行了较好的描述
*/

protected void Page_Load(object sender, EventArgs e)
{
//定义数据源
var numlist = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

//第一种定义方式:查询执行,定义了query对象后,实质上没有做任何的检索操作,待后面用到foreach后才执行这个query查询;
var query = from i in numlist
where i > 3 && i < 8
orderby i descending
select i;
//select query
foreach (var a in query)
{
Response.Write(a.ToString()
+ "<br />");
}

//第二种定义方式:立刻执行,将Linq查询强制转换为某种类型,这样赋值给变量;
var query01 = (from i in numlist
where i % 2 == 0
orderby i ascending
select i).Reverse
<int>().ToArray();//经此,query01的类型为int[]
foreach (var a in query01)
{
Response.Write(a.ToString()
+ "<br />");
}

//第三:连接两个Linq查询的结果集,关键方法(Contact),排除数组中的元素4和5
var query02 = (from a in numlist
where a % 2 == 0 && a != 4
orderby a descending
select a).Concat(
from b
in numlist
where b % 2 == 1 && b != 5
orderby b ascending
select b);
foreach (var c in query02)
{
Response.Write(c.ToString()
+ "<br />");
}
//第四:使用group by 子句,执行Linq查询
IList<GoodsEntity> goodsList = new List<GoodsEntity>();
for (var i = 1; i <= 20; i++)
{
goodsList.Add(
new GoodsEntity(i.ToString(), "GoodsName", (i < 10 ? "001" : "002")));
}
var query03
= from goods in goodsList
where goods.ClsID.Length > 0
group goods by goods.ClsID into jh
select jh;
/*根据多个字段/条件分组
var query04 = from goods in goodsList
group goods by new { goods.GdId, goods.ClsID } into jh
select jh;
*/
/* 查询条件保存至匿名类中,
* 以下查询将结果保存至一个匿名类中,并赋予属性:clsid,g,属性可以随便加,不过要注明每个属性的类型
var query05 = from goods in goodsList
group goods by goods.ClsID into g
select new
{
clsid = g.Key,
g
};
foreach (var x in query05)
{
Response.Write(x.clsid);
foreach (GoodsEntity gd in x.g)
{
Response.Write(gd.Name + "<br />");
}
}
*/

foreach (var gd in query03)//遍历每个组信息
{
Response.Write(
"<br />分类" + gd.Key.ToString() + "下的商品列表:<br />");
foreach (GoodsEntity good in gd)//遍历当前组下的列表信息
{
Response.Write(good.GdId
+ ":" + good.Name + "<br />");
}
}

//第五:关于使用Linq查询ArrayList数据源,需要指明变量的类型
var list = new ArrayList();
for (var i = 1; i < 20; i++)
{
list.Add(
new GoodsEntity(i.ToString(), "sweet", (i < 10 ? "001" : "002")));
}
var queryforArrayList
= from GoodsEntity goods in list// 在from后面加上goods的类型
where int.Parse(goods.GdId) >= 5 && int.Parse(goods.GdId) <= 10
select goods;
foreach (GoodsEntity good in queryforArrayList)
{
Response.Write(
string.Format("编号:{0},名称:{1}<br />", good.GdId, good.Name));
}
//第六:Linq查询的方法语法(扩展方法),直接用数据源.where/orderby ....
//数据源
string[] arr = new[] { "C#", "VB", "Flex", "JS", "Ajax" };
//IOrderedEnumerable<string> ss = arr.Where(ele => ele.Length > 2).OrderByDescending(ele => ele.Length);
string[] result = arr.Where(ele => ele.Length > 2).OrderByDescending(ele => ele.Length).ToArray<string>();//终于知道lamda表达式的好处了
string[] jieguo = arr.Where<string>(new Func<string, bool>(testss)).ToArray<string>();//这种写法与lamda写法效果相同,只是lamda更方便
Response.Write("<br />");
foreach (string s in jieguo)
{
Response.Write(s
+ ",");
}
//Func与Action委托
Func<int, int> fdel = getSquare;
//Func<int, int> xx = new Func<int, int>(getSquare);//此定义与以上定义方式一致
Response.Write("<br />使用Func<>泛型委托要求必须有返回值,本次返回值为:" + fdel(9).ToString() + "<br />");
Action act
= new Action(HelloWorld);//无参委托
act();
Action
<string> strAct = new Action<string>(WriteMsg);
strAct(
null);
strAct(
"C#.Action");
Response.Write(
"<br />次数:" + times.ToString());
}

//与lamda表达式对比,原理可能是差不多的
private bool testss(string s) { times++; if (s.Length > 2) return true; else return false; }

#region Method For Delegate
private int getSquare(int x)
{
return x * x;
}

private void HelloWorld()
{
Response.Write(
"<br />Hello,World!<br />");
}

private void WriteMsg(string msg)
{
if (msg != null)
Response.Write(
"<br />本次执行的参数为:" + msg.ToString());
else
Response.Write(
"本次执行没有参数。");
}
#endregion

}

//分类实体类
public class ClassEntity
{
private string clid;
private string name;
/// <summary>
/// 分类编号
/// </summary>
public string ClId { set; get; }
/// <summary>
/// 分了名称
/// </summary>
public string Name { set; get; }
}
//商品类
public class GoodsEntity
{
private string gdid;
private string name;
private string clsid;
/// <summary>
/// 商品编号
/// </summary>
public string GdId { set; get; }
/// <summary>
/// 商品名称
/// </summary>
public string Name { set; get; }
/// <summary>
/// 商品分类编号
/// </summary>
public string ClsID { set; get; }

public GoodsEntity() { }

public GoodsEntity(string id, string name, string clsid)
{
this.GdId = id;
this.Name = name;
this.ClsID = clsid;
}
}

关于Func委托与Action委托,推荐学习地址:http://www.cnblogs.com/wjfluisfigo/archive/2010/04/08/1512556.html

下载测试:代码

 

纠正一下:原来代码里面把lambda表达式写成了lamda表达式,呵呵,感谢 Arthas-Cui 的指出,也提醒下大家,跟着感觉走的时候偶尔还是要验证一下。

posted @ 2010-05-14 16:30 ESON 阅读(1812) 评论(3) 编辑

2010年5月13日

C#.NET -- 自定义事件

  最近研究了一下C#.NET的委托与事件这些东西,通过园子多篇文章的学习,基本上有了一个了解,现将一些基本的事件研究代码贴出来,分享一下,也希望大家能够多多指点。

 

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class BaseOnEvent : System.Web.UI.Page
{

/*
*事件:事件的本质就是一个委托链,在我们使用事件的时候,必须要声明对应的委托,而触发事件,其实就是在使用委托链。
*在执行某个事件时,先要看看有没有人订阅这个事件,没有人订阅的话,那就不用执行了(此时事件为null,执行会报错)。
*/

//申明一个委托
public delegate void Publish(int state);
//申明一个事件
public event Publish OnPublish;

protected void Page_Load(object sender, EventArgs e)
{
//首先需要知道有哪些对象关注这个事件,以下是设置关注者列表,默认Eson与Aliy都对此事件比较关注
OnPublish += MrEson.GetLatestNews;
OnPublish
+= MissAliy.GetLatestNews;
//记住:事件必须要在方法中触发
Test();
}

private void Test()
{
//首先处理该方法的一些逻辑
Response.Write("系统消息:hello,wrold!今天起,博客园正式开通啦!<br />");//发生第一个事件
//注意此处:事件分发是在该事件被订阅、被关注时,才被执行,如果该事件没有任何对象来关注,则不需要广播
//当然了,也可以在处理逻辑的中途广播给每个订阅者,以让每个关注者知道具体处理的进度或者状态等等
if (OnPublish != null)
OnPublish(
0);
//紧接着事件发生了一些变化,需要将这些发生的变化通知到每个关注者那里去
Response.Write("<br /><br />系统消息:恭喜恭喜,博客园又出新功能了!<br />");
if (OnPublish != null)
OnPublish(
1);
//又发生了新的变化,同样把变化的内容通知关注者
Response.Write("<br /><br />系统消息:从今日起,注册成为博客园会员,将会免费获得香港一日游的机会。<br />");
if (OnPublish != null)
OnPublish(
2);
Response.Write(
"<br /><br />系统消息:还有哪些用户在关注本次事件的,吃饭去了。。。<br />");
OnPublish
-= MissAliy.GetLatestNews;//在此取消订阅
if (OnPublish != null)
OnPublish(
1);

}

}

public class MrEson
{
//由于Eson对技术比较感兴趣,所以他对博客园的消息一直都在关注
public static void GetLatestNews(int state)
{
if (state == 0)
HttpContext.Current.Response.Write(
"知道了,博客园开通了。<br />");
else if (state==1)
HttpContext.Current.Response.Write(
"哦,博客园又出新功能了,还可以在线聊天。<br />");
else if (state==2)
HttpContext.Current.Response.Write(
"恩,博客园真是越来越好了,哈哈..<br />");
}
}

public class MissAliy
{
//Aliy就不一样了,他只关注那些大的新闻,小的新闻就直接不理
public static void GetLatestNews(int state)
{
if (state == 0)
HttpContext.Current.Response.Write(
"我是Miss Aliy,呵呵,我的网站也马上上线了。<br />");
else if (state == 1)
HttpContext.Current.Response.Write(
"恩,博客园还是挺不错的,不过跟我比起来还有点距离。<br />");
else if (state == 2)
{
//new BaseOnEvent().OnPublish -= MissAliy.GetLatestNews;
//不能在这里取消订阅,要取消订阅只有在发生事件的方法体内取消,本次取消无效
HttpContext.Current.Response.Write("哎,没意思,我还是写我的代码吧....<br />");
}
}
}

 

推荐几篇写的比较好的文章,也是有关委托与事件的:

http://www.cnblogs.com/wudiwushen/archive/2010/04/20/1698795.html,系列篇,通俗易懂。

http://www.cnblogs.com/markhe/archive/2009/08/26/1554710.html,这个是一个委托作为返回值和参数做的计算器。

 

posted @ 2010-05-13 16:07 ESON 阅读(444) 评论(1) 编辑

2010年5月12日

Javascript 类

摘要: Javascript中定义类的方式网上流传有很多种,什么工厂方式、构造函数方式、原型方式等等,这里拿我一般用的比较多的方式说说。  1.创建一个类,定义一些属性和简单方法  JS简单类代码  2.静态属性、静态方法、构造函数  静态属性和静态方法使用到关键字prototype,定义方式:classname.prototype.属性名=value ,classname.prototype.Metho...阅读全文

posted @ 2010-05-12 09:40 ESON 阅读(209) 评论(0) 编辑

2010年4月28日

比Jquery的document.ready更快的方法

new
function() {
    dom = [];
    dom.isReady = false;
    dom.isFunction = function(obj) {
        return Object.prototype.toString.call(obj) === "[object Function]";

    }
    dom.Ready = function(fn) {
        dom.initReady();
        //如果没有建成DOM树,则走第二步,存储起来一起杀
        if (dom.isFunction(fn)) {
            if (dom.isReady) {
                fn();
                //如果已经建成DOM,则来一个杀一个

            } else {
                dom.push(fn);
                //存储加载事件

            }

        }

    }
    dom.fireReady = function() {
        if (dom.isReady) return;
        dom.isReady = true;
        for (var i = 0, n = dom.length; i < n; i++) {
            var fn = dom[i];
            fn();

        }
        dom.length = 0;
        //清空事件

    }
    dom.initReady = function() {
        if (document.addEventListener) {
            document.addEventListener("DOMContentLoaded", 
            function() {
                document.removeEventListener("DOMContentLoaded", arguments.callee, false);
                //清除加载函数
                dom.fireReady();

            },
            false);

        } else {
            if (document.getElementById) {
                document.write("<script id=\"ie-domReady\" defer='defer'src=\"//:\"><\/script>");
                document.getElementById("ie-domReady").onreadystatechange = function() {
                    if (this.readyState === "complete") {
                        dom.fireReady();
                        this.onreadystatechange = null;
                        this.parentNode.removeChild(this)

                    }

                };

            }

        }

    }

}

这个是上次在博客园看到的一篇文章,经测试,确实比jquery的$(document).ready(function(){....})更快,并且在ie和火狐等主流浏览器上都没问题,

原文地址:http://www.cnblogs.com/rubylouvre/archive/2010/04/15/1712780.html

posted @ 2010-04-28 09:23 ESON 阅读(1944) 评论(5) 编辑

仅列出标题  

导航

统计

公告