unicorn.net

我的連結

Blog Stats

每月文章

隨筆分類

影像集

.net

blog

forum

friends

jQuery

open source

tools

web

Friday, October 03, 2008 #

有一天 Visual Studio 用內建的Web Server 啟動網站變的非常慢

一開始還以為是我的幻覺,還不斷的回想,是不是己前就這麼慢,是我變的比較沒耐心,專案何時變的那麼龐大?啟動竟然要10幾秒?

中間做了些測試,譬sql 連線,一些啟動優化,檢測httpModules花費時間,甚至磁碟檢查重組,暫停google search,移除最近安裝的軟體,不過都沒有解決問題,當我認命開始說服自己,網站就是那麼慢時,但放到 iis 上時卻又正常了。

好啦,最後終於找到原因,我之前把 visual studio 2008查閱asp.net 的原始碼功能打開了,我在 Options->Dbugging->Symbols 的 Symbols Symbol file (.pdb) locations: 設定了 http://referencesource.microsoft.com/symbols,我猜或許是這網站掛了吧,先把這個功能暫時關掉就正常了。

posted @ 12:50 PM | Feedback (0)

Thursday, September 04, 2008 #

Json.Net 從 1.31 換到 3.0

Json.Net是一套將物件序列成Json的字串、Json字串反序列回物件的程式庫

其實1.31版我還蠻習慣,在稍微修改後也一直用的好好的,激發我想跟上去的點,是今天試了3.0才發現,作者早就把不能序列Null、Value Type的封印解開了,再加上他有給SilverLight的版本(小加分),又看到 Rick Strahl 為 Json.Net 寫的 DataSet、DataTable、DataRow 的 Converter 要新版才能用(這可能會用到吧?)。

開始更新其實還蠻順利的,要克服的點都在預期內

  1. 序列日期: 原本1.31 是序列成 new Date(ticks),前端直接的js直接eval即可拿到Date object
        但到了3.0是序列成 asp.net的json日期格式 "\/Date(ticks)\/”,如果想迎向新的格式,
        相關參考 Truly's 微軟ASP.NET AJAX中日期類型的JSON處理 
        如果想將日期序列成原本格式,將JavaScriptDateTimeConverter序列時加入即可
            JsonSerializer json = new JsonSerializer();
            json.Converters.Add(new JavaScriptDateTimeConverter());
  2. 因為我原本的專案仍在 .net 2.0 下運作,但Json.Net 3.0版己經是用 VS2008 Net3.5下開發,讓.Net 2.0可以運行 .Net 3.5 的技巧可參考 CMHuang's 在 .NET 2.0 SP1 使用 LINQ (PLINQ) 及一些 Benchmark,主要是抽出 System.Core.Dll 給 .net 2.0 使用,另一個方式是引用 LINQBridge (把它想成 System.Core 的精簡版),我試過也是可行,重新編譯Json.Net時會有一個非必要的method仍有錯,把該method移除即可。

posted @ 11:50 PM | Feedback (1)

Tuesday, September 02, 2008 #

XML序列化出來卻無法用XmlDocument讀取,因為utf8的BOM

今天碰到一個小麻煩,XML序列化出來的資料,竟不能用 XmlDocument 讀取,出現錯誤訊息
Data at the root level is invalid. Line 1, position 1.
查了一下,序列化後資料最前面多了3 個byte [239,187,191],如果以字元來看是 65279,
也就是所謂的BOM(宣告文件是用utf8編碼)

這是原本的程式:

        public string Serialize(object obj) {
            //更改產生後的 xml namespace
            XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
            xmlNameSpace.Add("", "");
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            settings.Indent = true;
            settings.CheckCharacters =false;            

            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            MemoryStream stream = new MemoryStream();
            using (XmlWriter writer = XmlWriter.Create(stream, settings)) {
                serializer.Serialize(writer, obj, xmlNameSpace);                
            }
            return Encoding.UTF8.GetString(stream.ToArray());
        }

雖然知道原因,但卻不知道是怎麼產生該如何控制,於是打開了vs2008的 debug .net framework
的功能,一步一步追,查到是 settings.Encoding 的設定會影響,
然後再看到UTF8Encoding建構時有encoderShouldEmitUTF8Identifier參數可以設定
settings.Encoding = Encoding.UTF8;
改成
settings.Encoding = new UTF8Encoding(false);

搞定囉.

posted @ 6:14 PM | Feedback (1)

Wednesday, August 06, 2008 #

用繼承Form解Url Rewrite Postback會回到Rewrite前的Url問題, 卻碰上Validator Controls會失效

標題就快把狀況說完了,再稍微解釋一下

Url Rewrite 是讓你的網址,譬如原本的 http://localhost/post.aspx?id=303&page=7 重寫成 http://localhost/post/303/7.aspx ,據說這能讓搜尋引擎更方便的搜尋你的網站,或是拿來在特定的網頁間傳值(這是感受的問題? 我就是覺得一直帶出 ?id=333&page=7  有些不專業)。

那通常我是自己寫 HttpModule 來處理,用 context.RewritePath(newPath, false); 來重寫網址,當然這些不是本文重點,因為網路上詳細的文章多的是,假設網址改寫成功,第一個會碰到的難題是,雖然可以正確的  rewrite ,但在 postback 後,網址又會回到 ?id=303&page=7,這個的解法有2種,Rickel's blog 有詳細的程式碼,我們是選了繼承改寫 HtmlForm 的方式解,一開始也好好的,雖然會因此無法切換到 design mode, 但因為我也少用該模式就算了,只是呢 ~好景不長,幾天後才然發現,原本運作正常的驗證控制項都沒作用了:( ,花了一段時間的debug 才找到原因,如果page使用驗證控制項,他的 form 會產生如下的語法 <form name="aspnetForm" method="post" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm">,但是改寫的 HtmlForm 不會產生 onsubmit 的部份。

那我的解法如下

1 public class RewriteForm : System.Web.UI.HtmlControls.HtmlForm { 2 protected override void RenderAttributes(HtmlTextWriter writer) { 3 writer.WriteAttribute("name", this.Name); 4 base.Attributes.Remove("name"); 5 6 writer.WriteAttribute("method", this.Method); 7 base.Attributes.Remove("method"); 8 9 this.Attributes.Render(writer); 10 11 base.Attributes.Remove("action"); 12 13 //重新把 javascript:return WebForm_OnSubmit(); 加回 onsubmit 14 //以修正使用 RewriteForm 驗證控制項的Client驗證功能失效 15 //因為 ClientOnSubmitEvent 是Page的internal 的屬性,所以才用反射來取值 16 string clientOnSubmitEvent = 17 (string)typeof(Page).GetMethod("get_ClientOnSubmitEvent", 18 BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic) 19 .Invoke(this.Page, null); 20 if (String.IsNullOrEmpty(clientOnSubmitEvent) == false) { 21 writer.WriteAttribute("onsubmit", 22 clientOnSubmitEvent); 23 } 24 25 if (base.ID != null) 26 writer.WriteAttribute("id", base.ClientID); 27 } 28 }

posted @ 5:51 PM | Feedback (0)

Thursday, July 17, 2008 #

開發控制項之我做過的小蠢事, Template 誤用。

工作中偶爾要寫控制項,因為偶爾,所以常常會忘了該怎麼開始,而他的那些Attributes讓我混亂,通常我的對應之道,是打開Reflector.Net,找一個類似的控制項看他的原始碼,通常會順利,但偶爾還是做了一些蠢事。

 

這是今天要做的控制項,上面DIV包DIV放標題與圖示,然後是內容,然後是DIV等的結束標籤,我希望控制項輸入的內容,呈現時直接套用該風格,我第一個直覺是想到LoginView,就是那個設定依登入狀況顯示不同畫面的,打開他的原始碼,一看原來他是用Template來做,這個我有點概念,於是開始拼拼湊湊出底下的程式碼,運作起來也是可行的,然後我就回家了。

 

 

 

 

使用方式

<blog:PageBlockControl ID="block" runat="server">
	<Template>
		<ul>
			<li><a href="javascript:void(0)">balaba 1</a></li>
			<li><a href="javascript:void(0)">balaba 2</a></li>
			<li><a href="javascript:void(0)">balaba 3</a></li>
		</ul>
	</Template>
</blog:PageBlockControl>
PageBlockControl.cs
    [ParseChildren(true), DefaultProperty("Template")]
    public classPageBlockControl : Control, INamingContainer {    

        private ITemplate _template;
        [Browsable(false), DefaultValue((string)null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(MyPageBlockControl))]
        public ITemplate Template {
            get {return _template;}
            set { _template = value; }
        }

        protected override void CreateChildControls() {

            LiteralControl header = new LiteralControl(String.Format(@"
<div class='module'>
	<div class='module_top'>
		<div class='module_head'>
			{0}</div>
	</div>
	<div class='module_body'>
		<div class='module_content'>", "My Title"));

            LiteralControl footer = new LiteralControl(String.Format(@"
		</div>
		<div class='module_content_bottom'>
			...more<img src='{0}' width='16' height='13' /></div>
	</div>
	<div class='module_bottom'>
	</div>
</div>", this.ResolveClientUrl("~/image/more.gif")));

            Control container = new Control();
            Template.InstantiateIn(container);
            this.Controls.Add(header);
            this.Controls.Add(container);
            this.Controls.Add(footer);
        }
    }

 

 

回到家後腦袋清醒些,再想想我的需求,應該只要模仿 Panel 就可以了吧? 沒事弄個Template出來做什麼呢,底下是我迷途知返後修改的第2個版本。

使用方式

<blog:PageBlockControl2 ID="block" runat="server">
	<ul>
		<li><a href="javascript:void(0)">balaba 1</a></li>
		<li><a href="javascript:void(0)">balaba 2</a></li>
		<li><a href="javascript:void(0)">balaba 3</a></li>
	</ul>
</blog:PageBlockControl2>
PageBlockControl2.cs
    [ParseChildren(false), PersistChildren(true)]
    public class SpacePageBlockControl2 : Control {
        protected override void Render(HtmlTextWriter writer) {
            writer.Write(String.Format(@"
<div class='module'>
	<div class='module_top'>
		<div class='module_head'>
			{0}</div>
	</div>
	<div class='module_body'>
		<div class='module_content'>", "My Title"));
            
            base.Render(writer);
            
            writer.Write(String.Format(@"
		</div>
		<div class='module_content_bottom'>
			...more<img src='{0}' width='16' height='13' /></div>
	</div>
	<div class='module_bottom'>
	</div>
</div>", this.ResolveClientUrl("~/image/more.gif")));
        }
    }

 

 

延伸參考資料(或許是本篇最有價值的部份):

The ParseChildren and PersistChildren attributes - Justin Lovell's Blog

其實微軟自己的文件也很詳細

posted @ 12:00 PM | Feedback (0)

Tuesday, July 15, 2008 #

判斷是 Debug 或 Release 模式編譯

  • Asp.Net :
        HttpContext.Current.IsDebuggingEnabled

 

  • DLL
        public static bool IsDebugDLL(string AssemblyName) {
            Assembly assembly = Assembly.LoadFrom(AssemblyName);
            object[] attributes = assembly.GetCustomAttributes(typeof(DebuggableAttribute), false);
            if (attributes.Length == 0) {
                return false;
            }
            foreach (Attribute attr in attributes) {
                if (attr is DebuggableAttribute) {
                    DebuggableAttribute d = attr as DebuggableAttribute;
                    return d.IsJITOptimizerDisabled;
                }
            }
            return false;
        }

posted @ 2:06 AM | Feedback (0)

Friday, May 30, 2008 #

jQuery's plugin: doLater

我寫的簡單plugin。

  • 目的: 是要延幾秒(譬如3秒)再執行function,如果在這3秒內重複觸發的話,那原本動作取消,會再等3秒後才執行。
  • 使用時機:譬如要做 autocomplete,一般人可能連續輸入多個字元,如果每次keydown都到後端查符合的資料,那沒效能且沒必要,還不如等到使用者停下來再查,這時這個plugin 應該可以派上用場。
  • /* * @name doLater * @author unicorn liu * @param delay_ms 1000 = 1 second * @example $.doLater("job", 3000, function() { * //do it * }); */ jQuery.doLater = function(name, delay_ms, func_job) { if (window.doLaterTimerID == null) { window.doLaterTimerID = {}; } if (window.doLaterTimerID[name] != null) { window.clearTimeout(window.doLaterTimerID[name]); } window.doLaterTimerID[name] = window.setTimeout( function() { window.doLaterTimerID[name] = null; func_job.call(); }, delay_ms); }

posted @ 3:10 PM | Feedback (0)

Tuesday, April 22, 2008 #

ControlAdapter的嘗試,應用在多國語

底下是2種Asp.Net底下,使用多國語的標準方式

  1. <asp:Literal ID="litMessage" runat="server" Text="<%$Resources: Welcome%>" />
    這裏會顯示 local resource 裏的 Welcome 裏的字串
  2. <asp:Literal ID="litMessage2" runat="server" meta:resourcekey="litMessage2" />
    這裏會顯示 local resource 裏的 litMessage2.Text 裏的字串

這種設計有什麼麻煩之處呢?

  1. 如果有一個地方要顯示的訊息 "歡迎到台灣",你又很堅持想分成3個字串"歡迎" "到" "台灣"來存放多國語資料 (假設你很堅持啦),那頁面就得這樣寫了

    <asp:Literal ID="litMessage" runat="server" Text="<%$Resources: Welcome%>" /><asp:Literal ID="litMessage2" runat="server" Text="<%$Resources: To%>" /><asp:Literal ID="litMessage3" runat="server" Text="<%$Resources: Taiwan%>" />

    是不是很麻煩呢? 如果可以這樣
    <asp:Literal ID="litMessage" runat="server" Text="{$Welcome} {$To} {$Taiwan}" />
    甚至是 <span>{$Welcome} {$To} {$Taiwan}</span>

  2. 如果是多國語在javascrpit 裏,一般我習慣把js寫在 head 裏面,大概是會是這樣
    <head runat="server">	
    	<script language="javascript">
    	window.onload = function() {
    		var msg = '<%=this.GetLocalResourceObject("Welcome") %>';		
    		alert(msg);
    	}
    	</script>
    </head>
     

    這時的多國語得改用<%=this.GetLocalResourceObject("Welcome") %>,這樣不一致的用法,是不是容易讓人困惑? 如果可以這樣

    <head runat="server">	
    	<script language="javascript">
    	window.onload = function() {
    		var msg = '${Welcome}';		
    		alert(msg);
    	}
    	</script>
    </head>
 

底下提供一個可能方案,其實如果知道 ControlAdapter 是作什麼,大概也猜的出來接下來會做什麼,ControlAdapter 是在不改變原本程式碼的情況下,插入或是改寫控制項在Render行為。那針對Literal 就寫一個LiteralAdapter

namespace Adapter {
    public class LiteralAdapter : ControlAdapter {
        protected override void Render(HtmlTextWriter writer) {
            Literal literal = (Literal)this.Control;
            literal.Text = AdapterUtil.TranslateString(literal.Text);
            base.Render(writer);
        }
    }
}

AdapterUtil.TranslateString() 作用是將 ${Welcome} 從資源檔撈出比對替換,那 <span>...span> 或 Header 裏的 script,這些html/js,在Asp.Net裏是放置於 LitertalControl 控制項,於是乎就再寫LiteralControlAdapter

namespace Adapter {
    public class LiteralControlAdapter : ControlAdapter {
        protected override void Render(HtmlTextWriter writer) {
            LiteralControl literal = (LiteralControl)this.Control;
            literal.Text = AdapterUtil.TranslateString(literal.Text);
            base.Render(writer);
        }
    }
}

 

我揣測這樣的替換機制,應該會比原來作法效能差些,那要得到方便失去效能就看個人囉。另外我也沒在工作中實證,有興趣的話就下載回去玩玩。

posted @ 2:55 AM | Feedback (2)

Friday, April 04, 2008 #

修正 Koogra 讀取 Sheet Name ,如果是中文會變亂碼的問題

Koogra 一套讀取Excel 的類別庫,雖然作者很久沒更新了,但它簡單好用讀取快速,是我讀取excel時最佳選擇,但今天碰到了一個問題,當 sheet's name 用中文命名時,用程式讀取sheet's name會變亂碼,還好他是開放原始碼,花了點時間看看,做了底下修改,至於為什麼我知道這樣改?  我是參考 MyXls 的原始碼,是另一套還在持續發展中有點bug但同時可寫/讀excel檔的類別庫。

 

將 \Excel\Records\BoundSheetRecord.cs 34~38行

ushort nameLen = reader.ReadUInt16();
StringBuilder nb = new StringBuilder(nameLen);
nb.Append(new string(reader.ReadChars(nameLen)));

_name = nb.ToString();

 

改成

 

ushort nameLen = (ushort)reader.ReadByte();
bool compressed = (reader.ReadByte() * 0x01) == 0;

if (!compressed) {
    nameLen *= 2;
}

byte[] charBytes = reader.ReadBytes(nameLen);

if (compressed) {
    //decompress
    byte[] wideBytes = new byte[charBytes.Length * 2];
    for (int i = 0; i < charBytes.Length; i++)
        wideBytes[2 * i] = charBytes[i];
    charBytes = wideBytes;
}

_name = new string(Encoding.Unicode.GetChars(charBytes));

posted @ 3:32 AM | Feedback (8)

Thursday, April 03, 2008 #

SilverLight 觸發前端JavaScript事件

SilverLight:
HtmlPage.Window.Invoke("unicorn", 33, new DateTime(1976, 3, 11));
會觸發底下 window 的 sayUserInfo 事件,並且傳入3個參數  name, age, birthday

JavaScript:

	<script type="text/javascript">
	window.sayUserInfo = function(name,age,birthday) { 
		alert(name);
		alert(age);
		alert("民國" + new String(birthday.getFullYear()-1911) + "");
	};
	</script>
 
如果 Invoke 事件時,要傳入物件當參數,那物件的宣告要貼上 ScriptableType 標籤

SilverLight:

HtmlPage.Window.Invoke("sayUserInfo2",
    new UserInfo("unicorn", 33, new DateTime(1976, 3, 11)));


[ScriptableType]
public class UserInfo {
    private string name;
    private int age;
    private DateTime? birthday;

    public UserInfo(string name, int age, DateTime? birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public string Name {
        get { return name; }
        set { name = value; }
    }

    public int Age {
        get { return age; }
        set { age = value; }
    }

    public DateTime? Birthday {
        get { return birthday; }
        set { birthday = value; }
    }
}

 

JavaScript:

	<script type="text/javascript">
	window.sayUserInfo2 = function(user) {
		alert(user.Name);
		alert(user.Age);
		alert("民國" + new String(user.Birthday.getFullYear()-1911) + "");
	};
	</script>	

posted @ 2:07 AM | Feedback (0)

Wednesday, April 02, 2008 #

SilverLight: 頁面傳參數到SilverLight

用initParams param,如果參數只有一個,譬如value="file_types=rar"

如果多個則用逗號隔開,譬如 value="file_types=rar,file_size_limit=2048000"

 

Client端如下

		<object id="Xaml1" data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="400" height="300">
			<param name="source" value="ClientBin/SilverlightApplication1.xap"/>
			<param name="onError" value="onSilverlightError" />
			<param name="onLoad" value="pluginLoaded" />
			<param name="background" value="white" />
			<param name="initParams" value="file_types=rar,file_size_limit=2048000" /> 
			
			<a href="http://go.microsoft.com/fwlink/?LinkID=108182" style="text-decoration: none;">
     			<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
			</a>
		</object>
 

SilverLight - App.xaml.cs

        private void Application_Startup(object sender, StartupEventArgs e) {
            // Load the main control
            this.RootVisual = new Page();
            Option.FileTypes = ((Dictionary<string, string>)(e.InitParams))["file_types"];
        }

posted @ 1:58 AM | Feedback (0)

Tuesday, April 01, 2008 #

取得影像檔的長寬

SWF 長寬
http://www.codeproject.com/KB/graphics/ReaderSWFHeader.aspx

FVL 長寬
http://www.moitah.net/

 

後來看到更強的 MediaInfo,swf,flv,rmvb,wmv 通通都可以,真是太神了,不過因為是c++寫的dll ,所以會asp.net 要用會稍微麻煩一點,主要是asp.net web site project 會將程式編譯到 %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\ ,所以就算把MediaInfo.dll放到bin底下, [DllImport("MediaInfo.dll")] 時仍會找不到,那解決方式可能是

  1. 改成絕對路徑,譬如 [DllImport(@"c:\web\demosite\bin\MediaInfo.dll")]
  2. 在Global的Application_Start 時,複制MediaInfo.Dll到 AppDomain.CurrentDomain.DynamicDirectory

另外, 也有64位元版本dll 也有source喔

posted @ 12:12 PM | Feedback (0)

Friday, March 28, 2008 #

3個RIA的Chart

名字:FusionCharts Free v2
語言:Flash
網址:http://www.fusioncharts.com/free/
版權:商業可用


名字:Visifire
語言:SilverLight
網址:http://www.visifire.com/index.php
版權:GPL

名字:Open Flash Chart
語言:Flash
網址:http://teethgrinder.co.uk/open-flash-chart/
網址:免費(有源碼),作者還寫了為什麼要免費的心路歷程,因為他花錢買了別公司的Chart元件,發現了裏面有bug 跟軟體公司反應,但卻被拖了很久,問題一直沒有被妥善處,也沒有獲得應有的尊重,這讓他興起這自己動手做的動機,他的結論是"千萬不要惹毛客戶啊"
相關連結: Open Flash Chart Lib

posted @ 5:41 PM | Feedback (0)

Sunday, February 17, 2008 #

有關XML序列化的小技巧

 

1.如果你序列出的文件,XML表頭是 utf-16 而不是 utf-8 ,請參考這篇

 

 

2.如果你不想要 prefix ns 的宣告,想讓

<?xml version="1.0" encoding="utf-8"?> <DemoUser xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> </DemoUser>

變成

<?xml version="1.0" encoding="utf-8"?> <DemoUser> </DemoUser>

那底下的code會有幫助

XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("","");

序列時把 xmlNameSpace 加入, serializer.Serialize(writer, serObj, xmlNameSpace)

 

 

3.避免循環參考,可以用 XmlIgnore 標籤,譬如分類裏有很產品,而產品裏又有分類資料,序列時就會沒完沒了,那如果要針對分類做序列化,因為分類會自動帶出產品資料,那產品裏的分類參考就該 XmlIgnore

 

4.如果序列的物件裏有用到 Set 或其它集合,丟出沒有預設存取子(default accessor)的Exception

所謂default accessor是指

public T this[int idx] {
    get {
    }
    set {
    }
}

那解法可以是繞過去,用可以序列化的porpery 來取代不能序列的,譬如底下,隱藏起不能序列的 Roles, 改用 RoleArray 來做取代。

[XmlIgnore]
public SortedSet<Role> Roles {
    get { return roles; }
    set { roles = value; }
}

[XmlArray(ElementName="Roles")]
public Role[] RoleArray {
    get { return new List<Role>(roles).ToArray(); }
    set { }
}

另一個解法,就是繼承再實作 default accessor,這得視情況而定

譬如先前我用 SortedSet 無法做XML序列,我就寫了SortedSetProxy 繼承 SortedSet 並實作 default accessor 。

public class SortedSetProxy<T> : SortedSet<T> { private bool needUpdate = false; private List<T> list = new List<T>(); public T this[int idx] { get { if (needUpdate) { list = new List<T>(this.InternalDictionary.Keys); needUpdate = false; } return list[idx]; } } public override bool Add(T o) { needUpdate = true; return base.Add(o); } public override void Clear() { needUpdate = true; base.Clear(); } public override bool Remove(T o) { needUpdate = true; return base.Remove(o); } }

posted @ 6:00 PM | Feedback (0)

Thursday, February 14, 2008 #

想在 .Net 裏頭用 Set Collection (使用 Iesi.Collections.dll)

功能: 主要是取得2個Collection 裏,相同、相異、聯集的部份
必需加入的dll: Iesi.Collections.dl
範例:

補充:
1. 如果順序是重要的,那 HashedSet 可以改成 SortedSet
2. 如果用SortedSet, 集合內的物件必需繼承IComparable介面
3. 更詳盡的介紹可參考 Add Support for "Set" Collections to .NET
4.Iesi.Collection.dll 可在 NHibernate 專案裏找到, 裏面的版本加上對泛型的支援

posted @ 8:10 PM | Feedback (1)