
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
	<head><meta forua="true" http-equiv="Cache-Control" content="max-age=0" /></head><card id="MainCard" title="&#x6B22;&#x8FCE;&#x5149;&#x4E34;"><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a><br/>&nbsp;</p><p><b>&#x6807;&#x9898;&#x3A;</b> &#x45;&#x66;&#x66;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x20;&#x43;&#x23;&#x20;&#x539F;&#x5219;&#x32;&#x34;&#xFF1A;&#x9009;&#x62E9;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x800C;&#x4E0D;&#x662F;&#x547D;&#x4EE4;&#x5F0F;&#x7F16;&#x7A0B;</p><p><b>&#x4F5C;&#x8005;&#x3A;</b> &#x64;&#x6E;&#x61;&#x77;&#x6F;</p><p><b>&#x65E5;&#x671F;&#x3A;</b> &#x32;&#x30;&#x30;&#x39;&#x2D;&#x31;&#x32;&#x2D;&#x33;&#x31;&#x20;&#x30;&#x37;&#x3A;&#x34;&#x32;&#x20;&#x50;&#x4D;</p><p><b>&#x5206;&#x7C7B;&#x3A;</b> <a href="wap.asp?do=showLog&amp;cateID=5">&#x57;&#x65;&#x62;&#x7F16;&#x7A0B;</a></p><p><b>&#x5185;&#x5BB9;&#x3A;</b> &#x4E0E;&#x547D;&#x4EE4;&#x5F0F;&#x7F16;&#x7A0B;&#x76F8;&#x6BD4;&#xFF0C;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x53EF;&#x4EE5;&#x7528;&#x66F4;&#x7B80;&#x5355;&#xFF0C;&#x66F4;&#x6E05;&#x695A;&#x7684;&#x65B9;&#x6CD5;&#x6765;&#x63CF;&#x8FF0;&#x8F6F;&#x4EF6;&#x7684;&#x884C;&#x4E3A;&#x3002;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x5C31;&#x662F;&#x8BF4;&#x7528;&#x7533;&#x660E;&#x6765;&#x5B9A;&#x4E49;&#x7A0B;&#x5E8F;&#x7684;&#x884C;&#x4E3A;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x5199;&#x4E00;&#x4E9B;&#x6307;&#x4EE4;&#x3002;&#x5728;C#&#x91CC;&#xFF0C;&#x4E5F;&#x548C;&#x5176;&#x5B83;&#x5927;&#x591A;&#x6570;&#x8BED;&#x8A00;&#x4E00;&#x6837;&#xFF0C;&#x4F60;&#x7684;&#x5927;&#x591A;&#x6570;&#x7A0B;&#x5E8F;&#x90FD;&#x662F;&#x547D;&#x4EE4;&#x5F0F;&#x7684;&#xFF1A;&#x5728;&#x7A0B;&#x5E8F;&#x4E2D;&#x5199;&#x4E00;&#x4E2A;&#x65B9;&#x6CD5;&#x6765;&#x5B9A;&#x4E49;&#x884C;&#x4E3A;&#x3002;&#x5728;C#&#x4E2D;&#xFF0C;&#x4F60;&#x5728;&#x7F16;&#x7A0B;&#x65F6;&#x4F7F;&#x7528;&#x7279;&#x6027;&#x5C31;&#x662F;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x3002;&#x4F60;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x7279;&#x6027;&#x5230;&#x7C7B;&#xFF0C;&#x5C5E;&#x6027;&#xFF0C;&#x6570;&#x636E;&#x6210;&#x5458;&#xFF0C;&#x6216;&#x8005;&#x662F;&#x65B9;&#x6CD5;&#x4E0A;&#xFF0C;&#x7136;&#x540E;.Net&#x8FD0;&#x884C;&#x65F6;&#x5C31;&#x4F1A;&#x4E3A;&#x4F60;&#x6DFB;&#x52A0;&#x4E00;&#x4E9B;&#x884C;&#x4E3A;&#x3002;&#x8FD9;&#x6837;&#x7533;&#x660E;&#x7684;&#x76EE;&#x7684;&#x5C31;&#x662F;&#x7B80;&#x5355;&#x6613;&#x7528;&#xFF0C;&#x800C;&#x4E14;&#x6613;&#x4E8E;&#x9605;&#x8BFB;&#x548C;&#x7EF4;&#x62A4;&#x3002;<br/>&#x8BA9;&#x6211;&#x4EEC;&#x4EE5;&#x4E00;&#x4E2A;&#x4F60;&#x5DF2;&#x7ECF;&#x4F7F;&#x7528;&#x8FC7;&#x7684;&#x4F8B;&#x5B50;&#x5F00;&#x59CB;&#x3002;&#x5F53;&#x4F60;&#x5199;&#x4F60;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;ASP.Net Web&#x670D;&#x52A1;&#x65F6;&#xFF0C;&#x5411;&#x5BFC;&#x4F1A;&#x751F;&#x6210;&#x8FD9;&#x6837;&#x7684;&#x4EE3;&#x7801;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[WebMethod]<br/>public string HelloWorld()<br/>{<br/>&nbsp;&nbsp;return &#34;Hello World&#34;;<br/>}<br/>VS.net&#x7684;Web&#x670D;&#x52A1;&#x5411;&#x5BFC;&#x6DFB;&#x52A0;&#x4E86;[WebMethod]&#x7279;&#x6027;&#x5230;HelloWorld()&#x65B9;&#x6CD5;&#x4E0A;&#xFF0C;&#x8FD9;&#x5C31;&#x5B9A;&#x4E49;&#x4E86;HelloWorld&#x662F;&#x4E00;&#x4E2A;web&#x65B9;&#x6CD5;&#x3002;ASP.net&#x8FD0;&#x884C;&#x65F6;&#x4F1A;&#x4E3A;&#x4F60;&#x751F;&#x6210;&#x4EE3;&#x7801;&#x6765;&#x54CD;&#x5E94;&#x8FD9;&#x4E2A;&#x7279;&#x6027;&#x3002;&#x8FD0;&#x884C;&#x65F6;&#x751F;&#x6210;&#x7684;Web&#x670D;&#x52A1;&#x63CF;&#x8FF0;&#x8BED;&#x8A00;(WSDL)&#x6587;&#x6863;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x5305;&#x542B;&#x4E86;&#x5BF9;SOAP&#x8FDB;&#x884C;&#x63CF;&#x8FF0;&#x7684;&#x6587;&#x6863;&#xFF0C;&#x8C03;&#x7528;HelloWorld&#x65B9;&#x6CD5;&#x3002;ASP.net&#x4E5F;&#x652F;&#x6301;&#x8FD0;&#x884C;&#x65F6;&#x53D1;&#x9001;SOAP&#x8BF7;&#x6C42;HelloWorld&#x65B9;&#x6CD5;&#x3002;&#x53E6;&#x5916;&#xFF0C;ASP.net&#x8FD0;&#x884C;&#x65F6;&#x52A8;&#x6001;&#x7684;&#x751F;&#x6210;HTML&#x9762;&#x9875;&#xFF0C;&#x8FD9;&#x6837;&#x53EF;&#x4EE5;&#x8BA9;&#x4F60;&#x5728;IE&#x91CC;&#x6D4B;&#x8BD5;&#x4F60;&#x7684;&#x65B0;Web&#x670D;&#x52A1;&#x3002;&#x800C;&#x8FD9;&#x4E9B;&#x5168;&#x90E8;&#x662F;&#x524D;&#x9762;&#x7684;WebMethod&#x7279;&#x6027;&#x6240;&#x54CD;&#x5E94;&#x7684;&#x3002;&#x8FD9;&#x4E2A;&#x7279;&#x6027;&#x7533;&#x660E;&#x4E86;&#x4F60;&#x7684;&#x610F;&#x56FE;&#xFF0C;&#x800C;&#x4E14;&#x8FD0;&#x884C;&#x65F6;&#x786E;&#x4FDD;&#x5B83;&#x662F;&#x88AB;&#x652F;&#x6301;&#x7684;&#x3002;&#x4F7F;&#x7528;&#x7279;&#x6027;&#x7701;&#x4E86;&#x4F60;&#x4E0D;&#x5C11;&#x65F6;&#x95F4;&#xFF0C;&#x800C;&#x4E14;&#x9519;&#x8BEF;&#x4E5F;&#x5C11;&#x4E86;&#x3002;<br/>&#x8FD9;&#x5E76;&#x4E0D;&#x662F;&#x4E00;&#x4E2A;&#x795E;&#x8BDD;&#xFF0C;ASP.net&#x8FD0;&#x884C;&#x65F6;&#x4F7F;&#x7528;&#x53CD;&#x5C04;&#x6765;&#x65AD;&#x5B9A;&#x7C7B;&#x91CC;&#x7684;&#x54EA;&#x4E9B;&#x65B9;&#x6CD5;&#x662F;web&#x670D;&#x52A1;&#xFF0C;&#x5F53;&#x5B83;&#x4EEC;&#x53D1;&#x73B0;&#x8FD9;&#x4E9B;&#x65B9;&#x6CD5;&#x65F6;&#xFF0C;ASP.net&#x8FD0;&#x884C;&#x65F6;&#x5C31;&#x6DFB;&#x52A0;&#x4E00;&#x4E9B;&#x5FC5;&#x987B;&#x7684;&#x6846;&#x67B6;&#x4EE3;&#x7801;&#x5230;&#x8FD9;&#x4E9B;&#x65B9;&#x6CD5;&#x4E0A;&#xFF0C;&#x4ECE;&#x800C;&#x4F7F;&#x4EFB;&#x4F55;&#x6DFB;&#x52A0;&#x4E86;&#x8FD9;&#x4E9B;&#x4EE3;&#x7801;&#x7684;&#x65B9;&#x6CD5;&#x6210;&#x4E3A;web&#x65B9;&#x6CD5;&#x3002;<br/>[WebMethod] &#x7279;&#x6027;&#x53EA;&#x662F;.Net&#x7C7B;&#x5E93;&#x4F17;&#x591A;&#x7279;&#x6027;&#x4E4B;&#x4E00;&#xFF0C;&#x8FD9;&#x4E9B;&#x7279;&#x6027;&#x53EF;&#x80FD;&#x5E2E;&#x52A9;&#x4F60;&#x66F4;&#x5FEB;&#x7684;&#x521B;&#x5EFA;&#x6B63;&#x786E;&#x7684;&#x7A0B;&#x5E8F;&#x3002;&#x6709;&#x4E00;&#x4E9B;&#x7279;&#x6027;&#x5E2E;&#x52A9;&#x4F60;&#x521B;&#x5EFA;&#x5E8F;&#x5217;&#x5316;&#x7C7B;&#x578B;(&#x53C2;&#x89C1;&#x539F;&#x5219;25)&#x3002;&#x6B63;&#x5982;&#x4F60;&#x5728;&#x539F;&#x5219;4&#x91CC;&#x770B;&#x5230;&#x7684;&#xFF0C;&#x7279;&#x6027;&#x53EF;&#x4EE5;&#x63A7;&#x5236;&#x6761;&#x4EF6;&#x7F16;&#x8BD1;&#x3002;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4EE5;&#x4E0B;&#x5176;&#x5B83;&#x4E00;&#x4E9B;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x5199;&#x51FA;&#x4F60;&#x6240;&#x8981;&#x7684;&#x66F4;&#x5FEB;&#xFF0C;&#x66F4;&#x5C11;&#x9519;&#x8BEF;&#x7684;&#x4EE3;&#x7801;&#x3002;<br/>&#x4F60;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;.Net&#x6846;&#x67B6;&#x91CC;&#x81EA;&#x5E26;&#x7684;&#x4E00;&#x4E9B;&#x7279;&#x6027;&#x6765;&#x7533;&#x660E;&#x4F60;&#x7684;&#x610F;&#x56FE;&#xFF0C;&#x8FD9;&#x6BD4;&#x4F60;&#x81EA;&#x5DF1;&#x5199;&#x8981;&#x597D;&#x3002;&#x56E0;&#x4E3A;&#x8FD9;&#x6837;&#x82B1;&#x7684;&#x65F6;&#x95F4;&#x5C11;&#xFF0C;&#x66F4;&#x7B80;&#x5355;&#xFF0C;&#x800C;&#x4E14;&#x7F16;&#x8BD1;&#x5668;&#x4E5F;&#x4E0D;&#x4F1A;&#x51FA;&#x73B0;&#x9519;&#x8BEF;&#x3002;<br/>&#x5982;&#x679C;&#x9884;&#x7F6E;&#x7684;&#x7279;&#x6027;&#x4E0D;&#x9002;&#x5408;&#x4F60;&#x7684;&#x9700;&#x6C42;&#xFF0C;&#x4F60;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684;&#x7279;&#x6027;&#x548C;&#x4F7F;&#x7528;&#x53CD;&#x5C04;&#x6765;&#x4F7F;&#x7528;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x7ED3;&#x6784;&#x3002;&#x505A;&#x4E3A;&#x4E00;&#x4E2A;&#x4F8B;&#x5B50;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x7279;&#x6027;&#xFF0C;&#x7136;&#x800C;&#x5173;&#x8054;&#x5230;&#x4EE3;&#x7801;&#x4E0A;&#xFF0C;&#x8BA9;&#x7528;&#x6237;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x7279;&#x6027;&#x6765;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x53EF;&#x4EE5;&#x6392;&#x5E8F;&#x7684;&#x7C7B;&#x578B;&#x3002;&#x4E00;&#x4E2A;&#x4F8B;&#x5B50;&#x6F14;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6DFB;&#x52A0;&#x8FD9;&#x4E2A;&#x7279;&#x6027;&#xFF0C;&#x8BE5;&#x7279;&#x6027;&#x5B9A;&#x4E49;&#x4E86;&#x4F60;&#x60F3;&#x5982;&#x4F55;&#x5728;&#x4E00;&#x4E2A;&#x5BA2;&#x6237;&#x96C6;&#x5408;&#x4E2D;&#x6392;&#x5E8F;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[DefaultSort( &#34;Name&#34; )]<br/>public class Customer<br/>{<br/>&nbsp;&nbsp;public string Name<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _name; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;set { _name = value; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public decimal CurrentBalance<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _balance; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public decimal AccountValue<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return calculateValueOfAccount();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>DefaultSort&#x7279;&#x6027;&#xFF0C;Nane&#x5C5E;&#x6027;&#xFF0C;&#x8FD9;&#x5C31;&#x6697;&#x793A;&#x4E86;&#x4EFB;&#x4F55;Customer&#x7684;&#x96C6;&#x5408;&#x5E94;&#x8BE5;&#x4EE5;&#x5BA2;&#x6237;&#x540D;&#x5B57;&#x8FDB;&#x884C;&#x6392;&#x5E8F;&#x3002;DefaultSort&#x7279;&#x6027;&#x4E0D;&#x662F;.Net&#x6846;&#x67B6;&#x7684;&#x4E00;&#x90E8;&#x4EFD;&#xFF0C;&#x4E3A;&#x4E86;&#x5B9E;&#x73B0;&#x5B83;&#xFF0C;&#x4F60;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;DefaultSortAttribute&#x7C7B;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[AttributeUsage( AttributeTargets.Class |<br/>&nbsp;&nbsp;AttributeTargets.Struct )]<br/>public class DefaultSortAttribute : System.Attribute<br/>{<br/>&nbsp;&nbsp;private string _name;<br/>&nbsp;&nbsp;public string Name<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _name; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;set { _name = value; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public DefaultSortAttribute( string name )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_name = name;<br/>&nbsp;&nbsp;}<br/>}<br/>&#x540C;&#x6837;&#xFF0C;&#x4F60;&#x8FD8;&#x5FC5;&#x987B;&#x5199;&#x4E00;&#x4E9B;&#x4EE3;&#x7801;&#xFF0C;&#x6765;&#x5BF9;&#x4E00;&#x4E2A;&#x96C6;&#x5408;&#x8FD0;&#x884C;&#x6392;&#x5E8F;&#xFF0C;&#x800C;&#x8BE5;&#x96C6;&#x5408;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x662F;&#x6DFB;&#x52A0;&#x4E86;DefaultSort&#x7279;&#x6027;&#x7684;&#x5BF9;&#x8C61;&#x3002;&#x4F60;&#x5C06;&#x7528;&#x5230;&#x53CD;&#x5C04;&#x6765;&#x53D1;&#x73B0;&#x6B63;&#x786E;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x7136;&#x540E;&#x6BD4;&#x8F83;&#x4E24;&#x4E2A;&#x4E0D;&#x540C;&#x5BF9;&#x8C61;&#x7684;&#x5C5E;&#x6027;&#x503C;&#x3002;&#x4E00;&#x4E2A;&#x597D;&#x6D88;&#x606F;&#x662F;&#x4F60;&#x53EA;&#x7528;&#x5199;&#x4E00;&#x6B21;&#x8FD9;&#x6837;&#x7684;&#x4EE3;&#x7801;&#x3002;<br/>&#x4E0B;&#x4E00;&#x6B65;&#xFF0C;&#x4F60;&#x8981;&#x5199;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86;IComparer&#x63A5;&#x53E3;&#x7684;&#x7C7B;&#x3002;(&#x5728;&#x539F;&#x5219;26&#x4E2D;&#x4F1A;&#x8BE6;&#x7EC6;&#x7684;&#x5145;&#x5206;&#x8BA8;&#x8BBA;&#x6BD4;&#x8F83;&#x3002;) ICompare&#x6709;&#x4E00;&#x4E2A;CompareTo()&#x65B9;&#x6CD5;&#x6765;&#x6BD4;&#x8F83;&#x4E24;&#x4E2A;&#x7ED9;&#x5B9A;&#x7C7B;&#x578B;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x628A;&#x7279;&#x6027;&#x653E;&#x5728;&#x5B9E;&#x73B0;&#x4E86;IComparable&#x7684;&#x7C7B;&#x4E0A;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x6392;&#x5E8F;&#x987A;&#x5E8F;&#x4E86;&#x3002;&#x6784;&#x9020;&#x51FD;&#x6570;&#x5BF9;&#x4E8E;&#x901A;&#x7528;&#x7684;&#x6BD4;&#x8F83;&#xFF0C;&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#x9ED8;&#x8BA4;&#x7684;&#x6392;&#x5E8F;&#x5C5E;&#x6027;&#x6807;&#x8BB0;&#xFF0C;&#x800C;&#x8FD9;&#x4E2A;&#x6807;&#x8BB0;&#x662F;&#x57FA;&#x4E8E;&#x5DF2;&#x7ECF;&#x6BD4;&#x8F83;&#x8FC7;&#x7684;&#x7C7B;&#x578B;&#x3002;Compare&#x65B9;&#x6CD5;&#x5BF9;&#x4EFB;&#x4F55;&#x7C7B;&#x578B;&#x7684;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x8FDB;&#x884C;&#x6392;&#x5E8F;&#xFF0C;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x7684;&#x6392;&#x5E8F;&#x5C5E;&#x6027;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;internal class GenericComparer : IComparer<br/>{<br/>&nbsp;&nbsp;// Information about the default property:<br/>&nbsp;&nbsp;private readonly PropertyDescriptor _sortProp;<br/>&nbsp;&nbsp;// Ascending o&#114; descending.<br/>&nbsp;&nbsp;private readonly bool _reverse = false;<br/>&nbsp;&nbsp;// Construct for a type<br/>&nbsp;&nbsp;public GenericComparer( Type t ) :<br/>&nbsp;&nbsp;&nbsp;&nbsp;this( t, false )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Construct for a type<br/>&nbsp;&nbsp;// and a direction<br/>&nbsp;&nbsp;public GenericComparer( Type t, bool reverse )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_reverse = reverse;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// find the attribute,<br/>&nbsp;&nbsp;&nbsp;&nbsp;// and the name of the sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the default sort attributes on the type:<br/>&nbsp;&nbsp;&nbsp;&nbsp;object [] a = t.GetCustomAttributes(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typeof( DefaultSortAttribute ),false );<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the PropertyDescriptor for that property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( a.Length &gt; 0 )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultSortAttribute sortName = a[ 0 ] as&nbsp;&nbsp; DefaultSortAttribute;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string name = sortName.Name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Initialize the sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PropertyDescriptorCollection props =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeDescriptor.GetProperties( t );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( props.Count &gt; 0 )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ( PropertyDescriptor p in props )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( p.Name == name )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Found the default sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp = p;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Compare method.<br/>&nbsp;&nbsp;int IComparer.Compare( object left,<br/>&nbsp;&nbsp;&nbsp;&nbsp;object right )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// null is less than any real object:<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (( left == null ) &amp;&amp; ( right == null ))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( left == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( right == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( _sortProp == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the sort property from each object:<br/>&nbsp;&nbsp;&nbsp;&nbsp;IComparable lField =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp.GetValue( left ) as IComparable;<br/>&nbsp;&nbsp;&nbsp;&nbsp;IComparable rField =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp.GetValue( right ) as IComparable;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int rVal = 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( lField == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( rField == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;rVal = lField.CompareTo( rField );<br/>&nbsp;&nbsp;&nbsp;&nbsp;return ( _reverse ) ? -rVal : rVal;<br/>&nbsp;&nbsp;}<br/>}<br/>&#x8FD9;&#x4E2A;&#x901A;&#x7528;&#x7684;&#x6BD4;&#x8F83;&#x5BF9;&#x4EFB;&#x4F55;Customers &#x96C6;&#x5408;&#x53EF;&#x4EE5;&#x8FDB;&#x884C;&#x6392;&#x5E8F;&#xFF0C;&#x800C;&#x8FD9;&#x4E2A;Customers&#x662F;&#x7528;DefaultSort&#x7279;&#x6027;&#x7533;&#x660E;&#x4E86;&#x7684;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;CustomerList.Sort( new GenericComparer(<br/>&nbsp;&nbsp;typeof( Customer )));<br/>&#x5B9E;&#x73B0;GenericComparer&#x7684;&#x4EE3;&#x7801;&#x5229;&#x7528;&#x4E86;&#x4E00;&#x4E9B;&#x9AD8;&#x7EA7;&#x7684;&#x6280;&#x672F;&#xFF0C;&#x4F7F;&#x7528;&#x53CD;&#x5C04;(&#x53C2;&#x89C1;&#x539F;&#x5219;43)&#x3002;&#x4F46;&#x4F60;&#x5FC5;&#x987B;&#x5199;&#x4E00;&#x904D;&#x8FD9;&#x6837;&#x7684;&#x4EE3;&#x7801;&#x3002;&#x4ECE;&#x8FD9;&#x4E2A;&#x89C2;&#x70B9;&#x4E0A;&#x770B;&#xFF0C;&#x4F60;&#x6240;&#x8981;&#x505A;&#x7684;&#x5C31;&#x662F;&#x6DFB;&#x52A0;&#x7A7A;&#x4E0A;&#x5C5E;&#x6027;&#x5230;&#x5176;&#x5B83;&#x4EFB;&#x4F55;&#x7C7B;&#x4E0A;&#xFF0C;&#x7136;&#x800C;&#x4F60;&#x5C31;&#x53EF;&#x4EE5;&#x5BF9;&#x8FD9;&#x4E9B;&#x5BF9;&#x8C61;&#x7684;&#x96C6;&#x5408;&#x8FDB;&#x884C;&#x80FD;&#x7528;&#x7684;&#x6392;&#x5E8F;&#x4E86;&#x3002;&#x5982;&#x679C;&#x4F60;&#x4FEE;&#x6539;&#x4E86;DefaultSort&#x7279;&#x6027;&#x7684;&#x53C2;&#x6570;&#xFF0C;&#x4F60;&#x5C31;&#x8981;&#x4FEE;&#x6539;&#x7C7B;&#x7684;&#x884C;&#x4E3A;&#x3002;&#x800C;&#x4E0D;&#x7528;&#x4FEE;&#x6539;&#x6240;&#x6709;&#x7684;&#x7B97;&#x6CD5;&#x3002;<br/>&#x8FD9;&#x79CD;&#x7533;&#x660E;&#x5F0F;&#x4E60;&#x60EF;&#x662F;&#x5F88;&#x6709;&#x7528;&#x7684;&#xFF0C;&#x5F53;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684;&#x7533;&#x660E;&#x53EF;&#x4EE5;&#x8BF4;&#x660E;&#x4F60;&#x7684;&#x610F;&#x56FE;&#x65F6;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x4F60;&#x907F;&#x514D;&#x91CD;&#x590D;&#x7684;&#x4EE3;&#x7801;&#x3002;&#x518D;&#x53C2;&#x8003;GenericComparer&#x7C7B;&#xFF0C;&#x4F60;&#x5E94;&#x8BE5;&#x53EF;&#x4EE5;&#x4E3A;&#x4F60;&#x521B;&#x5EFA;&#x7684;&#x4EFB;&#x4F55;&#x7C7B;&#x578B;&#xFF0C;&#x5199;&#x4E00;&#x4E2A;&#x4E0D;&#x540C;&#x7684;(&#x800C;&#x4E14;&#x662F;&#x662F;&#x76F4;&#x63A5;&#x4E86;&#x5F53;&#x7684;)&#x6392;&#x5E8F;&#x7B97;&#x6CD5;&#x3002;&#x8FD9;&#x79CD;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x7684;&#x597D;&#x5904;&#x5C31;&#x662F;&#x4F60;&#x53EA;&#x7528;&#x5199;&#x4E00;&#x6B21;&#x80FD;&#x7528;&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x7136;&#x540E;&#x5C31;&#x53EF;&#x4EE5;&#x7528;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684;&#x7533;&#x660E;&#x4E3A;&#x6BCF;&#x4E2A;&#x7C7B;&#x578B;&#x521B;&#x5EFA;&#x884C;&#x4E3A;&#x3002;&#x5173;&#x952E;&#x662F;&#x884C;&#x4E3A;&#x7684;&#x6539;&#x53D8;&#x662F;&#x57FA;&#x4E8E;&#x5355;&#x4E2A;&#x7533;&#x660E;&#x7684;&#xFF0C;&#x4E0D;&#x662F;&#x57FA;&#x4E8E;&#x4EFB;&#x4F55;&#x7B97;&#x6CD5;&#x7684;&#x3002;GenericComparer&#x53EF;&#x4EE5;&#x5728;&#x4EFB;&#x4F55;&#x7528;DefaultSort&#x7279;&#x6027;&#x4FEE;&#x9970;&#x4E86;&#x7684;&#x7C7B;&#x578B;&#x4E0A;&#x5DE5;&#x4F5C;&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x53EA;&#x987B;&#x8981;&#x5728;&#x7A0B;&#x5E8F;&#x91CC;&#x4F7F;&#x7528;&#x4E00;&#x4E24;&#x6B21;&#x6392;&#x5E8F;&#x529F;&#x80FD;&#xFF0C;&#x5C31;&#x6309;&#x5E38;&#x89C4;&#x7B80;&#x5355;&#x7684;&#x65B9;&#x6CD5;&#x5199;&#x5427;&#x3002;&#x7136;&#x800C;&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x7684;&#x7A0B;&#x5E8F;&#x5BF9;&#x4E8E;&#x540C;&#x6837;&#x7684;&#x884C;&#x4E3A;&#xFF0C;&#x53EF;&#x80FD;&#x987B;&#x8981;&#x5728;&#x51E0;&#x5341;&#x4E2A;&#x7C7B;&#x578B;&#x4E0A;&#x5B9E;&#x73B0;&#xFF0C;&#x90A3;&#x4E48;&#x80FD;&#x7528;&#x7684;&#x7B97;&#x6CD5;&#x4EE5;&#x53CA;&#x7533;&#x660E;&#x5F0F;&#x7684;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#x4F1A;&#x7701;&#x4E0B;&#x5F88;&#x591A;&#x65F6;&#x95F4;&#xFF0C;&#x800C;&#x4E14;&#x5728;&#x957F;&#x65F6;&#x95F4;&#x7684;&#x8FD0;&#x884C;&#x4E2D;&#x4E5F;&#x662F;&#x5F88;&#x6709;&#x529B;&#x7684;&#x3002;&#x4F60;&#x4E0D;&#x5E94;&#x8BE5;&#x4E3A;WebMethod&#x7279;&#x6027;&#x5199;&#x4EE3;&#x5168;&#x90E8;&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x4F60;&#x5E94;&#x8BE5;&#x628A;&#x8FD9;&#x4E00;&#x6280;&#x672F;&#x5C55;&#x5F00;&#x5728;&#x4F60;&#x81EA;&#x5DF1;&#x7684;&#x7B97;&#x6CD5;&#x4E0A;&#x3002;&#x539F;&#x5219;42&#x91CC;&#x8BA8;&#x8BBA;&#x4E86;&#x4E00;&#x4E2A;&#x4F8B;&#x5B50;&#xFF1A;&#x5982;&#x4F55;&#x4F7F;&#x7528;&#x7279;&#x6027;&#x6765;&#x5EFA;&#x7ACB;&#x4E00;&#x4E2A;&#x9644;&#x52A0;&#x547D;&#x4EE4;&#x53E5;&#x67C4;&#x3002;&#x5176;&#x5B83;&#x7684;&#x4F8B;&#x5B50;&#x53EF;&#x80FD;&#x8FD8;&#x5305;&#x62EC;&#x4E00;&#x4E9B;&#x5728;&#x5B9A;&#x4E49;&#x9644;&#x52A0;&#x5305;&#x5EFA;&#x7ACB;&#x52A8;&#x6001;&#x7684;web UI&#x9762;&#x9875;&#x65F6;&#x7684;&#x5176;&#x5B83;&#x5185;&#x5BB9;&#x3002;<br/>&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x662F;&#x4E00;&#x4E2A;&#x5F88;&#x6709;&#x529B;&#x7684;&#x5DE5;&#x5177;&#xFF0C;&#x5F53;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x7279;&#x6027;&#x6765;&#x8868;&#x660E;&#x4F60;&#x7684;&#x610F;&#x56FE;&#x65F6;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528;&#x7279;&#x6027;&#xFF0C;&#x6765;&#x51CF;&#x5C11;&#x5728;&#x5927;&#x91CF;&#x7C7B;&#x4F3C;&#x7684;&#x624B;&#x5199;&#x7B97;&#x6CD5;&#x4E2D;&#x51FA;&#x73B0;&#x903B;&#x8F91;&#x9519;&#x8BEF;&#x7684;&#x53EF;&#x80FD;&#x3002;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x521B;&#x5EFA;&#x4E86;&#x66F4;&#x6613;&#x4E8E;&#x9605;&#x8BFB;&#xFF0C;&#x6E05;&#x6670;&#x7684;&#x4EE3;&#x7801;&#x3002;&#x8FD9;&#x4E5F;&#x5C31;&#x610F;&#x5473;&#x7740;&#x4E0D;&#x7BA1;&#x662F;&#x73B0;&#x5728;&#x8FD8;&#x662F;&#x5C06;&#x6765;&#xFF0C;&#x90FD;&#x4F1A;&#x5C11;&#x51FA;&#x73B0;&#x9519;&#x8BEF;&#x3002;&#x5982;&#x679C;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;.Net&#x6846;&#x67B6;&#x91CC;&#x5B9A;&#x4E49;&#x7684;&#x7279;&#x6027;&#xFF0C;&#x90A3;&#x5C31;&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x80FD;&#xFF0C;&#x8003;&#x8651;&#x9009;&#x62E9;&#x521B;&#x5EFA;&#x4F60;&#x81EA;&#x5DF1;&#x7684;&#x7279;&#x6027;&#xFF0C;&#x8FD9;&#x6837;&#x4F60;&#x53EF;&#x4EE5;&#x5728;&#x5C06;&#x6765;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x521B;&#x5EFA;&#x540C;&#x6837;&#x7684;&#x884C;&#x4E3A;&#x3002;<br/>========================================================&nbsp;&nbsp;&nbsp;&nbsp; <br/>Item 24: Prefer Declarative to Imperative Programming<br/>Declarative programming can often be a simpler, more concise way to describe the behavior of a software program than imperative programming. Declarative programming means that you define the behavior of your program using declarations instead of by writing instructions. In C#, as in many other languages, most of your programming is imperative: You write methods that define the behavior of your programs. You practice declarative programming using attributes in C#. Youattach attributes to classes, properties, data members, o&#114; methods, and the .NET runtime adds behavior for you. This declarative approach is simpler to implement and easier to read and maintain.<br/>Let&#39;s begin with an obvious example that you&#39;ve already used. When you wrote your first ASP.NET web service, the wizard generated this sequence of code:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[WebMethod]<br/>public string HelloWorld()<br/>{<br/>&nbsp;&nbsp;return &#34;Hello World&#34;;<br/>}<br/>The VS .NET Web Service wizard added the [WebMethod] attribute to the HelloWorld() method. That declared HelloWorld as a web method. The ASP.NET runtime cr&#101;ates code for you in response to the presence of this attribute. The runtime cr&#101;ated the Web Service Description Language (WSDL) document, which contains a description for the SOAP document that invokes the HelloWorld method. ASP.NET also adds support in the runtime to route SOAP requests to your HelloWorld method. In addition, the ASP.NET runtime dynamically cr&#101;ates HTML pages that enable you to test your new web service in IE. That&#39;s all in response to the presence of the WebMethod attribute. The attribute declared your intent, and the runtime ensured that the proper support was there. Using the attribute takes much less time and is much less error prone.<br/>It&#39;s really not magic. The ASP.NET runtime uses reflection to determine which methods in your class are web methods. When they are found, the ASP.NET runtime can add all the necessary framework code to turn any function into a web method.<br/>The [WebMethod] attribute is just one of many attributes that the .NET library defines that can help you cr&#101;ate correct programs more quickly. A number of attributes help you cr&#101;ate serializable types (see Item 25). As you saw in Item 4, attributes control conditional compilation. In those and other cases, you can cr&#101;ate the code you need faster and with less chance for errors using declarative programming. You should use these .NET Framework attributes to declare your intent rather than write your own code. It takes less time, it&#39;s easier, and the compiler doesn&#39;t make mistakes.<br/>If the predefined attributes don&#39;t fit your needs, you can cr&#101;ate your own declarative programming constructs by defining custom attributes and using reflection. As an example, you can cr&#101;ate an attribute and associated code to let users cr&#101;ate types that define the default sort o&#114;der using an attribute. A sample usage shows how adding the attribute defines how you want to sort a collection of customers:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[DefaultSort( &#34;Name&#34; )]<br/>public class Customer<br/>{<br/>&nbsp;&nbsp;public string Name<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _name; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;set { _name = value; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public decimal CurrentBalance<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _balance; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public decimal AccountValue<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return calculateValueOfAccount();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>The DefaultSort attribute e, the Name property. The implication is that any collection of Customers should be o&#114;dered by the customer name. The DefaultSort attribute is not part of the .NET Framework. To implement it, you need to cr&#101;ate the DefaultSortAttribute class:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;[AttributeUsage( AttributeTargets.Class |<br/>&nbsp;&nbsp;AttributeTargets.Struct )]<br/>public class DefaultSortAttribute : System.Attribute<br/>{<br/>&nbsp;&nbsp;private string _name;<br/>&nbsp;&nbsp;public string Name<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get { return _name; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;set { _name = value; }<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public DefaultSortAttribute( string name )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_name = name;<br/>&nbsp;&nbsp;}<br/>}<br/>You must still write the code to sort a collection of objects based on the presence of the DefaultSort attribute. You&#39;ll use reflection to find the correct property and then compare values of that property in two different objects. The good news is that you need to write this code only once.<br/>Next, you cr&#101;ate a class that implements IComparer. (Comparers are discussed in more detail in Item 26.) IComparerhas a version of CompareTo() that compares two objects of a given type, letting the target class, which implements IComparable, define the sort o&#114;der. The constructor for the generic comparer finds the default sort property descriptor based on the type being compared. The Compare method sorts two objects of any type, using the default sort property:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;internal class GenericComparer : IComparer<br/>{<br/>&nbsp;&nbsp;// Information about the default property:<br/>&nbsp;&nbsp;private readonly PropertyDescriptor _sortProp;<br/>&nbsp;&nbsp;// Ascending o&#114; descending.<br/>&nbsp;&nbsp;private readonly bool _reverse = false;<br/>&nbsp;&nbsp;// Construct for a type<br/>&nbsp;&nbsp;public GenericComparer( Type t ) :<br/>&nbsp;&nbsp;&nbsp;&nbsp;this( t, false )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Construct for a type<br/>&nbsp;&nbsp;// and a direction<br/>&nbsp;&nbsp;public GenericComparer( Type t, bool reverse )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_reverse = reverse;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// find the attribute,<br/>&nbsp;&nbsp;&nbsp;&nbsp;// and the name of the sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the default sort attributes on the type:<br/>&nbsp;&nbsp;&nbsp;&nbsp;object [] a = t.GetCustomAttributes(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typeof( DefaultSortAttribute ),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false );<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the PropertyDescriptor for that property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( a.Length &gt; 0 )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultSortAttribute sortName = a[ 0 ] as<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultSortAttribute;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string name = sortName.Name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Initialize the sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PropertyDescriptorCollection props =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeDescriptor.GetProperties( t );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( props.Count &gt; 0 )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ( PropertyDescriptor p in props )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( p.Name == name )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Found the default sort property:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp = p;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Compare method.<br/>&nbsp;&nbsp;int IComparer.Compare( object left,<br/>&nbsp;&nbsp;&nbsp;&nbsp;object right )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// null is less than any real object:<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (( left == null ) &amp;&amp; ( right == null ))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( left == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( right == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( _sortProp == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Get the sort property from each object:<br/>&nbsp;&nbsp;&nbsp;&nbsp;IComparable lField =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp.GetValue( left ) as IComparable;<br/>&nbsp;&nbsp;&nbsp;&nbsp;IComparable rField =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sortProp.GetValue( right ) as IComparable;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int rVal = 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( lField == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( rField == null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;rVal = lField.CompareTo( rField );<br/>&nbsp;&nbsp;&nbsp;&nbsp;return ( _reverse ) ? -rVal : rVal;<br/>&nbsp;&nbsp;}<br/>}<br/>The Generic comparer sorts any collection of Customers based on the property declared in the DefaultSort attribute:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;CustomerList.Sort( new GenericComparer(<br/>&nbsp;&nbsp;typeof( Customer )));<br/>The code to implement the GenericComparer makes use of advanced techniques, such as reflection (see Item 43). But you need to write it only once. From that point on, all you need to do is add the attribute to any class, and you can sort a collection of those objects using the generic comparer. If you change the parameter on the DefaultSort attribute, you change the class&#39;s behavior. You don&#39;t need to change any algorithms anywh&#101;re in your code.<br/>This declarative idiom is useful to avoid writing repetitivecode when a simple declaration can specify your intent. Look at the Generic Comparer class again. You could write different (and slightly simpler) versions of the sort algorithm for every type you cr&#101;ated. The advantage to using declarative programming is that you can write one generic class and let a simple declaration cr&#101;ate the behavior for each type. The key is that the behavior changes based on a single declaration, not based on any algorithm changes. The GenericComparer works for any type decorated with the DefaultSort attribute. If you need sorting functionality only once o&#114; twice in your application, write the simpler routines. However, if you might need the same behavior for many tens of different types in your program, the generic algorithm and the declarative solution will save you time and energy in the long run. You&#39;d never write all the code generated by the WebMethod attribute. You should expand on that technique for your own algorithms. Item 42 discusses one example: how to use attributes to build add-on command handlers. Other examples might include anything from defining add-on packages to building dynamic web page UIs.<br/>Declarative programming is a powerful tool. When you can use attributes to declare your intent, you save the possibility of logic mistakes in multiple similar hand-coded algorithms. Declarative programming cr&#101;ates more readable, cleaner code. That means fewer mistakes now and in the future. If you can use an attribute defined in the .NET Framework, do so. If not, consider the option of creating your own attribute definition so that you can use it to cr&#101;ate the same behavior in the future.</p><p> + <a href="#CommentCard">&#x67E5;&#x770B;&#x5F53;&#x524D;&#x65E5;&#x5FD7;&#x8BC4;&#x8BBA;</a> (0)</p><p>&nbsp;<br/><br/><a href="wap.asp?do=Login">&#x767B;&#x5F55;</a></p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.738&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card><card id="postCommentCard"><p><b>&#x6807;&#x9898;&#x3A;</b> <a href="#MainCard">&#x45;&#x66;&#x66;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x20;&#x43;&#x23;&#x20;&#x539F;&#x5219;&#x32;&#x34;&#xFF1A;&#x9009;&#x62E9;&#x7533;&#x660E;&#x5F0F;&#x7F16;&#x7A0B;&#x800C;&#x4E0D;&#x662F;&#x547D;&#x4EE4;&#x5F0F;&#x7F16;&#x7A0B;</a></p><p><br/>你没有权限发表评论</p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.738&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card><card id="CommentCard"><p>&#x6682;&#x65E0;&#x8BC4;&#x8BBA;</p><p><a href="#MainCard">&#x8FD4;&#x56DE;</a></p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.738&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card>
</wml>
