<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mingbo &#187; 接口</title>
	<atom:link href="http://shao.mingbo.de/tag/%e6%8e%a5%e5%8f%a3/feed/" rel="self" type="application/rss+xml" />
	<link>http://shao.mingbo.de</link>
	<description>包括教育技术，编程，互联网等方面的文章及随想。</description>
	<lastBuildDate>Thu, 26 Aug 2010 02:57:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>cSharp数组的学习笔记</title>
		<link>http://shao.mingbo.de/2009/11/29/arrays-notes-in-csharp/</link>
		<comments>http://shao.mingbo.de/2009/11/29/arrays-notes-in-csharp/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 05:01:21 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[.NET 编程]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[myNote]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[数组]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=302</guid>
		<description><![CDATA[这一章主要是2对接口的辨析让人纠结。不过，我们还是一对一对的来看，首先将要出场的是IEnumerable Vs IEnumerator. IEnumerable 接口中需要实现一个GetEnumerator()方法，它返回一个IEnumerator 接口。在IEnumerator 中有MoveNext()  方法和Reset() 方法，另外还有一个current 属性。这是他们之间的关系。 值得注意的是，不论是否声明继承了接口，在指定类中实现了一个返回IEnumerator 的方法，就可以手动的通过上述的这2个方法和1个属性，进行迭代了；同样的，不论是否有显式的声明，实现了一个返回IEnumerable 的方法，就可以通过foreach 进行迭代了。下面是我推荐的一个Demo: static void Main(string[] args) { testClass myTest = new testClass(); Console.WriteLine("由于在testClass 已经实现了 GetEnumerator()方法："); //直接使用foreach来进行迭代。 foreach (string a in myTest) { Console.WriteLine(a); } //手动迭代 Console.WriteLine(); Console.WriteLine("手动迭代："); IEnumerator enmuerator = myTest.GetEnumerator(); while (enmuerator.MoveNext()) { Console.WriteLine(enmuerator.Current.ToString()); } //之所以用手动迭代，是因为不能这样 //foreach (string a in enmuerator) //{ // [...]]]></description>
			<content:encoded><![CDATA[<p>这一章主要是2对接口的辨析让人纠结。不过，我们还是一对一对的来看，首先将要出场的是<strong>IEnumerable Vs IEnumerator. </strong></p>
<p>IEnumerable 接口中需要实现一个GetEnumerator()方法，它返回一个IEnumerator 接口。在IEnumerator 中有<strong>MoveNext()  方法</strong>和<strong>Reset() 方法</strong>，另外还有一个current 属性。这是他们之间的关系。</p>
<p><strong>值得注意的是</strong>，不论是否声明继承了接口，在指定类中实现了一个返回IEnumerator 的方法，就可以手动的通过上述的这2个方法和1个属性，进行迭代了；同样的，不论是否有显式的声明，实现了一个返回IEnumerable 的方法，就可以通过foreach 进行迭代了。下面是我推荐的一个Demo:</p>
<pre lang="csharp">
        static void Main(string[] args)
        {
            testClass myTest = new testClass();
            Console.WriteLine("由于在testClass 已经实现了 GetEnumerator()方法：");
            //直接使用foreach来进行迭代。
            foreach (string a in myTest)
            {
                Console.WriteLine(a);
            }

            //手动迭代
            Console.WriteLine();
            Console.WriteLine("手动迭代：");
            IEnumerator enmuerator = myTest.GetEnumerator();
            while (enmuerator.MoveNext())
            {
                Console.WriteLine(enmuerator.Current.ToString());
            }

            //之所以用手动迭代，是因为不能这样
            //foreach (string a in enmuerator)
            //{
            //    Console.WriteLine(a);
            //}
            //原因是，enmuerator不包含“GetEnumerator”的公共定义
            //foreach无法发现这个定义，但IEnumerable则不同

            Console.WriteLine();
            Console.WriteLine("IEnumerable 还是强悍一些：");
            foreach (string a in myTest.Reverse())
            {
                Console.WriteLine(a);
            }
        }

        class testClass
        {
            string[] cars ={ "BMW Li 5", "Mercedes-benz", "Hong Qi" };

             public IEnumerator GetEnumerator()
            {
                for (int i = 0; i < cars.Length; i++)
                    yield return cars[i];
            }

            public IEnumerable Reverse()
            {
                for (int i = cars.Length-1; i >= 0; i--)
                {
                    yield return cars[i];
                }
            }
        }
</pre>
<p>在介绍下面的接口之前，我还想补充一个有趣的继承关系：IEnumerable 是基类，接下里有ICollection 继承它，而Ilist 继承ICollection。伴随着这样的继承关系，自然地其实现的方法和属性那是越来越多的。接下来，我们该说说<strong>IComparable Vs IComparer </strong>了<strong>.</strong></p>
<p>IComparable 是为指定类型提供了CompareTo() 的方法[<span style="color: #ff0000;"><strong>必须</strong></span>]来比较自己 .当你将指定的类声明为一个数组时，想用sort() 方法来对数组中的对象进行排序，这时如果已经实现了IComparable 则会自动调用CompareTo() 来进行比较排序。</p>
<p>而IComparer则是为指定类型提供了一种<strong><span style="color: #ff0000;">附加</span>的比较机制</strong>。IComparer 附加的被实现为一个辅助比较的类，在该辅助类中提供一个Compare 方法[<strong><span style="color: #ff0000;">必须</span></strong>]。在指定对象的数组中，调用sort 方法时，只需传递一个该辅助类的实例，即可。由于是附加的，所以可以提供多种含有Compare 方法的辅助类，相比之下，IComparable 只能在指定类中实现一个CompareTo 的方法；从效能方面，2种方法的参数都是传递object。但不同的是，CompareTo只有一个参数。每次进行比较，Compare都需要2倍于前者的“装箱-拆箱”的操作。下面，我还是用一个Demo 来说明问题：</p>
<pre lang="csharp">
        static void Main(string[] args)
        {
            mobilePhone[] mp = { new mobilePhone("Sony Ericsson",2000M),
                                 new mobilePhone("Nokia",3000M),
                                 new mobilePhone("Samsung",1500M),
                                 new mobilePhone("Shan Zhai",800M),
                                 new mobilePhone("ABC",800M),
                                 new mobilePhone("ACC",700M)
                                };
            //------------
            Console.WriteLine("IComparable Demo:");
            Array.Sort(mp);
            foreach (mobilePhone m in mp)
            {
                Console.WriteLine(m);
            }
            Console.WriteLine();
            //------------
            Console.WriteLine("IComparer-makerASCEcomparer Demo:");
            Array.Sort(mp, mobilePhone.makerASCEcomparer());
            foreach (mobilePhone m in mp)
            {
                Console.WriteLine(m);
            }
            Console.WriteLine();
            //------------
            Console.WriteLine("IComparer-priceASCEcomparer Demo:");
            Array.Sort(mp, mobilePhone.priceASCEcomparer());
            foreach (mobilePhone m in mp)
            {
                Console.WriteLine(m);
            }
            Console.WriteLine();
            //------------
            Console.WriteLine("IComparer-priceDSCEcomparer Demo:");
            Array.Sort(mp, mobilePhone.priceDSCEcomparer());
            foreach (mobilePhone m in mp)
            {
                Console.WriteLine(m);
            }
            Console.WriteLine();
        }

        class mobilePhone:IComparable
        {
            private string maker;
            private decimal price;

            public mobilePhone(string maker,decimal price)
            {
                this.maker = maker;
                this.price = price;
            }

            public string Maker
            {
                get
                {
                    return maker;
                }
                set
                {
                    maker = value;
                }
            }

            public decimal Price
            {
                get
                {
                    return price;
                }
                set
                {
                    price = value;
                }
            }

            int IComparable.CompareTo(object x)
            {
                mobilePhone other = (mobilePhone)x;
                int result = this.price.CompareTo(other.price);
                if (result == 0)
                    this.maker.CompareTo(other.maker);
                return result;
            }

            private class priceASCE : IComparer
            {
                int IComparer.Compare(object x,object y)
                {
                    mobilePhone one = (mobilePhone)x;
                    mobilePhone other = (mobilePhone)y;

                    if (one.Price > other.Price)
                        return 1;
                    else if (one.Price == other.Price)
                        return 0;
                    else
                        return -1;

                }
            }

            public static IComparer priceASCEcomparer()
            {
                return (IComparer)new priceASCE();
            }

            private class priceDSCE : IComparer
            {
                int IComparer.Compare(object x, object y)
                {
                    mobilePhone one = (mobilePhone)x;
                    mobilePhone other = (mobilePhone)y;

                    if (one.Price < other.Price)
                        return 1;
                    else if (one.Price == other.Price)
                        return 0;
                    else
                        return -1;

                }
            }

            public static IComparer priceDSCEcomparer()
            {
                return (IComparer)new priceDSCE();
            }

            private class makerASCE : IComparer
            {
                int IComparer.Compare(object x, object y)
                {
                    mobilePhone one = (mobilePhone)x;
                    mobilePhone other = (mobilePhone)y;

                    int result = one.Maker.CompareTo(other.Maker);
                    return result;
                }
            }

            public static IComparer makerASCEcomparer()
            {
                return (IComparer)new makerASCE();
            }

            public override string ToString()
            {
                return "Mobile Made by " + Maker + ", And Its Price is " + Price.ToString("C");
            }
        }
</pre>
<p>其实，不得不说，不管是IComparable 还是IComparer 都能实现彼此的功能，IComparer 更符合人类排序比较的思维方式罢了。当然理性的对待问题：首先是要看对效能的需求，其次才是看个人的喜好了。</p>
<p>参考资料：<br />
MSDN——<a href="http://support.microsoft.com/kb/320727/en-us/">How to use the IComparable and IComparer interfaces in Visual C#</a></p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li>2009年11月28日 -- <a href="http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-two/" title="cSharp继承的学习笔记-PartTwo">cSharp继承的学习笔记-PartTwo</a></li><li>2009年12月22日 -- <a href="http://shao.mingbo.de/2009/12/22/how-to-use-backgroundworker-in-csharp/" title="cSharp中BackgroundWorker的用法">cSharp中BackgroundWorker的用法</a></li><li>2009年12月21日 -- <a href="http://shao.mingbo.de/2009/12/21/synchronize-class-design-in-csharp/" title="cSharp中同步类的设计">cSharp中同步类的设计</a></li><li>2009年12月20日 -- <a href="http://shao.mingbo.de/2009/12/20/paralize-thread-in-charp/" title="cSharp中给线程传递参数">cSharp中给线程传递参数</a></li><li>2009年12月19日 -- <a href="http://shao.mingbo.de/2009/12/19/asynchronous-delegate-in-csharp/" title="cSharp中异步委托的笔记">cSharp中异步委托的笔记</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2009/11/29/arrays-notes-in-csharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cSharp继承的学习笔记-PartTwo</title>
		<link>http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-two/</link>
		<comments>http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-two/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 07:06:56 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[.NET 编程]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[myNote]]></category>
		<category><![CDATA[密封]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[继承]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=297</guid>
		<description><![CDATA[本文承接于《cSharp继承的学习笔记-PartOne》，主要谈谈继承这一章节关于密封和接口中我认为重要的知识。 密封：对于类来说，不能继承该类；对方法来说，不能重写。 在《对象和类》中提到，结构本身是不支持类型继承，那是因为结构是隐式密封的。 在方法中或属性中使用sealed 关键字时，必须与override连用。 接口：只能包含方法，属性，索引和事件；不能包含构造函数（其本身，不允许实例化，何谈构造？），不允许运算符重载（引起.net 的其他语言不兼容的问题，如：VB） 接口可以理解为一种契约，当你和别人签订了契约，就有责任实现其中的每个方法，如若有一个方法没实现，那请不要签定该契约。当契约生效时，其他的c#代码便可通过接口知道该方法支持的特性。 相关文章2009年11月29日 -- cSharp数组的学习笔记2009年11月28日 -- cSharp继承的学习笔记-PartOne2009年12月22日 -- cSharp中BackgroundWorker的用法2009年12月21日 -- cSharp中同步类的设计2009年12月20日 -- cSharp中给线程传递参数]]></description>
			<content:encoded><![CDATA[<p>本文承接于《<a href="http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-one/" target="_blank">cSharp继承的学习笔记-PartOne</a>》，主要谈谈继承这一章节关于<strong>密封和接口</strong>中我认为重要的知识。</p>
<p><strong>密封</strong>：对于类来说，不能继承该类；对方法来说，不能重写。</p>
<ul>
<li>在《<a href="http://shao.mingbo.de/2009/11/26/object-and-class-in-csharp/" target="_blank">对象和类</a>》中提到，结构本身是不支持类型继承，那是因为结构是隐式密封的。</li>
<li>在方法中或属性中使用sealed 关键字时，必须与override连用。</li>
</ul>
<p><strong>接口</strong>：只能包含方法，属性，索引和事件；不能包含构造函数（其本身，不允许实例化，何谈构造？），不允许运算符重载（引起.net 的其他语言不兼容的问题，如：VB）</p>
<p><strong>接口</strong>可以理解为一种契约，当你和别人签订了契约，<span style="color: #ff0000;">就有责任实现其中的每个方法</span>，如若有一个方法没实现，那请不要签定该契约。当契约生效时，其他的c#代码便可通过接口知道该方法支持的特性。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li>2009年11月29日 -- <a href="http://shao.mingbo.de/2009/11/29/arrays-notes-in-csharp/" title="cSharp数组的学习笔记">cSharp数组的学习笔记</a></li><li>2009年11月28日 -- <a href="http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-one/" title="cSharp继承的学习笔记-PartOne">cSharp继承的学习笔记-PartOne</a></li><li>2009年12月22日 -- <a href="http://shao.mingbo.de/2009/12/22/how-to-use-backgroundworker-in-csharp/" title="cSharp中BackgroundWorker的用法">cSharp中BackgroundWorker的用法</a></li><li>2009年12月21日 -- <a href="http://shao.mingbo.de/2009/12/21/synchronize-class-design-in-csharp/" title="cSharp中同步类的设计">cSharp中同步类的设计</a></li><li>2009年12月20日 -- <a href="http://shao.mingbo.de/2009/12/20/paralize-thread-in-charp/" title="cSharp中给线程传递参数">cSharp中给线程传递参数</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2009/11/28/inheritance-notes-of-csharp-part-two/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
