﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-i am myself</title><link>http://www.cnblogs.com/buaaytt/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 08 Jan 2009 03:00:40 GMT</lastBuildDate><pubDate>Thu, 08 Jan 2009 03:00:40 GMT</pubDate><ttl>60</ttl><item><title>VS2005的一个bug</title><link>http://www.cnblogs.com/buaaytt/archive/2005/11/23/282937.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Wed, 23 Nov 2005 08:42:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/11/23/282937.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/282937.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/11/23/282937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/282937.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/282937.html</trackback:ping><description><![CDATA[今天在调试代码的时候发现了一个bug，本来打算feedback给MS，不过一搜索，才发现已经有人报告过这个bug了，而微软说在现在这个版本不会解决。Anyway，this is just FYI: <A href="http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=d36ae5cf-07f6-4c10-b40f-97a7b6a7ce0c">http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=d36ae5cf-07f6-4c10-b40f-97a7b6a7ce0c</A><img src ="http://www.cnblogs.com/buaaytt/aggbug/282937.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44363/" target="_blank">微软周五发布Windows 7 Beta 1 向公众开放</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>翻译MSDN文章 —— 泛型FAQ：最佳实践</title><link>http://www.cnblogs.com/buaaytt/archive/2005/11/06/270084.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Sun, 06 Nov 2005 08:20:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/11/06/270084.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/270084.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/11/06/270084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/270084.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/270084.html</trackback:ping><description><![CDATA[原文：<A href="http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dndotnet/html/BestPractices.asp">http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dndotnet/html/BestPractices.asp</A>&nbsp; 
<P>作者：<SPAN lang=EN-US>Juval Lowy</SPAN>（后面介绍中说微软将此人视为<SPAN lang=EN-US>Software Legend as one of the world's top .NET experts and industry leaders</SPAN>，名头很响亮啊。无奈本人孤陋寡闻，没听过）</P><SPAN>注：括号里的英文是我认为不好翻译的原文，如果您有更好的译法，请告诉我，谢谢。同时，对包含<SPAN lang=EN-US>generic</SPAN>的组合词语（如<SPAN lang=EN-US>generic type parameter</SPAN>，<SPAN lang=EN-US>generic method</SPAN>）参照<SPAN lang=EN-US>MSDN</SPAN>中文网站<SPAN lang=EN-US><A href="http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx" target=_blank><SPAN lang=EN-US>C# <SPAN lang=EN-US><SPAN lang=EN-US>泛型简介</SPAN></SPAN></SPAN></A>一文统一译作&#8220;一般&#8221;，虽然我认为并不好听。<BR>&nbsp; 
<P><STRONG>摘要</STRONG></P><SPAN>回顾关于使用泛型最佳实践的<SPAN lang=EN-US>FAQ<BR><BR><STRONG>内容<BR><BR></STRONG>什么时候我不应该使用泛型？<BR>对泛型我应该使用什么命名规范？<BR>我应该在泛型接口上面添加约束吗？<BR>如何处置（Dispose）泛型接口？<BR>可以对一般类型参数进行类型转换吗？<BR>对泛型类如何同步多线程访问？<BR>如何序列化泛型类？<BR><BR><STRONG>什么时候我不应该使用泛型？<BR><BR></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不使用泛型的主要原因就是跨目标（cross-targeting）——如果你要在.NET 1.1和.NET 2.0下编译相同的代码，那么由于只有.NET 2.0支持泛型，你就不能够使用泛型。<BR><BR>
<P><STRONG>对泛型我应该使用什么命名规范？<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </STRONG><SPAN lang=EN-US>我建议使用一个单独的大写字母来表示一般类型参数。如果你对类型参数没有其他的跟上下文有关的信息（<SPAN lang=EN-US>additional contextual information</SPAN>），你应该使用字母<SPAN lang=EN-US>T</SPAN>：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class MyClass&lt;T&gt;
{...}</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass(Of T)
   ...
End Class
</PRE>
<P>[C++]</P><PRE class=code>generic &lt;typename T&gt;
public ref class MyClass
{...};<BR></PRE>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在所有其他场合下，微软正式的对泛型的的命名规范指导是：</P>
<UL>
<LI><SPAN lang=EN-US>一般类型参数要有描述性的名字，除非一个单独的字母已经表示得很清楚，再增加描述性的名字也没有多大用处。</SPAN></LI></UL><SPAN lang=EN-US>
<P>[C#] </P><PRE>public interface ISessionChannel&lt;TSession&gt; 
{...}
public delegate TOutput Converter&lt;TInput,TOutput&gt;(TInput from);
</PRE>
<P>[Visual Basic] </P><PRE>Public Interface ISessionChannel(Of TSession)
   ... 
End Interface

Public Delegate Function Converter(Of TInput, TOutput)(ByVal input As TInput) As Toutput
</PRE>
<P>[C++] </P><PRE>generic &lt;typename TSession&gt;
public interface class ISessionChannel 
{...};
generic &lt;typename TInput, typename TOutput&gt;
public delegate TOutput Converter(TInput from);<BR></PRE><SPAN lang=EN-US>
<UL>
<LI><SPAN lang=EN-US>可以考虑在一般类型参数的名字中表示出添加给该一般类型参数的约束。例如，一个被约束到<SPAN lang=EN-US>ISession</SPAN>接口的参数可以起名为<SPAN lang=EN-US>TSession</SPAN>。</LI></UL>
<P><STRONG>我应该在泛型接口上面添加约束吗？</STRONG></P>
<P><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接口可以为其使用的范型类型添加约束，例如：<SPAN lang=EN-US>&nbsp; </SPAN></P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public interface ILinkedList&lt;T&gt; where T : IComparable&lt;T&gt;
{...}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Interface ILinkedList(Of T As IComparable(Of T))
   ...
End Interface
</PRE>
<P>[C++]</P><PRE class=code>generic &lt;typename T&gt; where T : IComparable&lt;T&gt;
public interface class ILinkedList
{...};<BR></PRE></SPAN>
<P><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是，你应该小心，在接口层面上定义约束还隐含有另外一层意思。为了强调接口与实现分离的思想，接口不应该包括任何一点实现的细节。虽然有很多方法可以用来实现范型接口，但是使用特定的类型参数毕竟是一种实现的细节。约束通常情况下会更加耦合（<SPAN lang=EN-US>couple</SPAN>）接口和特定的实现。</P>
<P><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 更好的方法是，为实现范型接口的类添加约束，保持接口本身没有约束：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class LinkedList&lt;T&gt; : ILinkedList&lt;T&gt; where T : IComparable&lt;T&gt;
{
   //Rest of the implementation  
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class LinkedList(Of T As IComparable(Of T))
       Implements ILinkedList(Of T)
' Rest of the implementation  
End Class
</PRE>
<P>[C++]</P><PRE class=code>generic &lt;typename T&gt; where T : IComparable&lt;T&gt; 
public ref class LinkedList : ILinkedList&lt;T&gt;
{
   //Rest of the implementation  
};<BR></PRE></SPAN>
<P><STRONG>如何处置（<SPAN lang=EN-US>Dispose</SPAN>）泛型接口？</STRONG></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在<SPAN lang=EN-US>C#</SPAN>和<SPAN lang=EN-US>Visual Basic</SPAN>中，如果你把一个一般类型参数的对象放在<SPAN lang=EN-US>using</SPAN>语句中，编译器无法知道客户端（<SPAN lang=EN-US>client</SPAN>）指定的实际类型是否支持<SPAN lang=EN-US>IDisposable</SPAN>接口。因此编译器不允许在<SPAN lang=EN-US>using</SPAN>语句中使用一般类型参数的实例。</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class MyClass&lt;T&gt; 
{
   public void SomeMethod(T t)
   {
      using(t)//Does not compile 
      {...}
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass(Of T)
   Public Sub SomeMethod(ByVal value As T)
      Using value ' Does not compile
      End Using
   End Sub
End Class<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，你可以强制约束类型参数支持<SPAN lang=EN-US>IDisposable</SPAN>接口：</P>
<P>[C#]</P><PRE class=code>public class MyClass&lt;T&gt; where T : IDisposable 
{
   public void SomeMethod(T t)
   {
      using(t)
      {...}
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass(Of T As IDisposable)
   Public Sub SomeMethod(ByVal value As T)
      Using value
      End Using
   End Sub
End Class<BR></PRE>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是你不应该这么做。这样做的问题在于你不能使用接口作为类型参数了，即使这个接口的基础类型（<SPAN lang=EN-US>underlying type</SPAN>）支持<SPAN lang=EN-US>IDisposable</SPAN>也不行：</P><PRE><SPAN lang=EN-US></SPAN></PRE>
<P>[C#]</P><PRE class=code>public interface IMyInterface
{}
public class MyOtherClass : IMyInterface,IDisposable 
{...}
public class MyClass&lt;T&gt; where T : IDisposable 
{
   public void SomeMethod(T t)
   {
      using(t)
      {...}
   }
}
MyOtherClass myOtherClass = new MyOtherClass();
MyClass&lt;IMyInterface&gt; obj = new MyClass&lt;IMyInterface&gt;();//Does not compile
obj.SomeMethod(myOtherClass); 
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Interface IMyInterface
End Interface

Public Class MyOtherClass
      Implements IMyInterface, IDisposable
   ...
End Class

Public Class SomeClass(Of T As IDisposable)
   Public Sub SomeMethod(ByVal value As T)
      Using value
      End Using
   End Sub
End Class

Dim myOtherClass As New MyOtherClass
Dim obj As New SomeClass(Of IMyInterface) ' Does not compile
obj.SomeMethod(myOtherClass)<BR></PRE>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作为替代，我建议你在<SPAN lang=EN-US>using</SPAN>语句里对一般类型参数使用<SPAN lang=EN-US>C#</SPAN>中的<SPAN lang=EN-US>as</SPAN>操作符或者<SPAN lang=EN-US>Visual Basic</SPAN>中的<SPAN lang=EN-US>TryCast</SPAN>操作符来允许接口作为一般类型参数使用：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class MyClass&lt;T&gt; 
{
   public void SomeMethod(T t)
   {
      using(t as IDisposable)
      {...}
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass(Of T)
   Public Sub SomeMethod(ByVal value As T)
      Using TryCast(value, IDisposable)
      End Using
   End Sub
End Class<BR></PRE></SPAN>
<P><STRONG>可以对一般类型参数进行类型转换吗？</STRONG></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于隐式转换，编译器只允许将一般类型参数转换为<SPAN lang=EN-US>object</SPAN>类型，或者其约束里指定的那个类型：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>interface ISomeInterface
{...}
class BaseClass
{...}
class MyClass&lt;T&gt; where T : BaseClass,ISomeInterface
{
   void SomeMethod(T t)
   {
      ISomeInterface obj1 = t;
      BaseClass      obj2 = t;
      object         obj3 = t;
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Interface ISomeInterface
   ...
End Interface

Class BaseClass
   ...
End Class

Class SomeClass(Of T As{BaseClass,ISomeInterface})

   Private Sub SomeMethod(ByVal value As T)
      Dim obj1 As ISomeInterface = value
      Dim obj2 As BaseClass = value
      Dim obj3 As Object = value
   End Sub
End Class
</PRE>
<P>[C++]</P><PRE class=code>interface class ISomeInterface
{...};
ref class BaseClass
{...};
generic &lt;typename T&gt; where T : BaseClass,ISomeInterface
ref class MyClass
{
   void SomeMethod(T t)
   {
      ISomeInterface ^obj1 = t;
      BaseClass      ^obj2 = t;
      Object         ^obj3 = t;
   }
};<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这种隐式转换当然是类型安全的，因为无效的转换在编译时就会被发现。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于显示转换，编译器允许将一般类型参数转换到任何接口，但是不能转换为类：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass&lt;T&gt; 
{
   void SomeMethod(T t)
   {
      ISomeInterface obj1 = (ISomeInterface)t;//Compiles
      SomeClass      obj2 = (SomeClass)t;     //Does not compile
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Interface ISomeInterface
   ...
End Interface

Class BaseClass
   ...
End Class

Class SomeClass(Of T)
   Private Sub SomeMethod(ByVal value As T)
      Dim obj1 As ISomeInterface = CType(value,ISomeInterface)' Compiles
      Dim obj2 As BaseClass = CType(value,BaseClass)' Does not compile
   End Sub
End Class
</PRE>
<P>[C++]</P><PRE class=code>interface class ISomeInterface
{...};
ref class SomeClass
{...};
generic &lt;typename T&gt;
ref class MyClass 
{
   void SomeMethod(T t)
   {
      ISomeInterface ^obj1 = (ISomeInterface ^)t;//Compiles
      SomeClass      ^obj2 = (SomeClass ^)t;     //Does not compile
   }
};<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是，你可以通过使用一个临时的<SPAN lang=EN-US>object</SPAN>类型变量来强制将一般类型参数转到到任何其他类型：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>class MyOtherClass
{...}

class MyClass&lt;T&gt; 
{
  
   void SomeMethod(T t)
   
   {
      object temp = t;
      MyOtherClass obj = (MyOtherClass)temp;
   
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Class MyOtherClass
   ...
End Class

Class SomeClass(Of T)
   Sub SomeMethod(ByVal value As T)
      Dim temp As Object = value
      Dim obj As MyOtherClass = CType(temp, MyOtherClass)
   End Sub
End Class
</PRE>
<P>[C++]</P><PRE class=code>ref class SomeClass
{...};

generic &lt;typename T&gt;
ref class MyClass 
{
  
   void SomeMethod(T t)
   
   {
      Object ^temp = t;
      SomeClass ^obj = (SomeClass ^)temp;
   
   }
};<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 毫无疑问，这样的显示转换是很危险的，因为如果实际使用的替代一般类型参数的类型不是从你要转换到的类型那里继承的话，就可能在运行时抛出异常。</P>
<P><SPAN lang=EN-US>[C#]</SPAN></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了避免这种转换时有异常的风险，一个更好的办法是使用<SPAN lang=EN-US>is</SPAN>或者<SPAN lang=EN-US>as</SPAN>操作符。如果一般类型参数是（<SPAN lang=EN-US>is</SPAN>）要查询的类型，<SPAN lang=EN-US>is </SPAN>操作符会返回<SPAN lang=EN-US>true</SPAN>，而<SPAN lang=EN-US>as</SPAN>操作符会在两个类型兼容的时候执行转换，否则将返回<SPAN lang=EN-US>null</SPAN>。</P>
<P><SPAN lang=EN-US>public class MyClass&lt;T&gt; <BR>{<BR>&nbsp;&nbsp; public void SomeMethod(T t)<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(t is int)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {...} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(t is LinkedList&lt;int,string&gt;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {...}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string str = t as string;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(str != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {...}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkedList&lt;int,string&gt; list = t as LinkedList&lt;int,string&gt;;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(list != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {...}<BR>&nbsp;&nbsp; }<BR>}</SPAN></P>
<P><SPAN lang=EN-US>[Visual Basic]</SPAN></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了避免这种转换时有异常的风险，一个更好的办法是使用<SPAN lang=EN-US>TypeOf</SPAN>和<SPAN lang=EN-US>TryCast</SPAN>操作符。如果一般类型参数是（<SPAN lang=EN-US>is</SPAN>）要查询的类型，<SPAN lang=EN-US>is </SPAN>操作符会返回<SPAN lang=EN-US>true</SPAN>。你也可以使用<SPAN lang=EN-US>TryCast</SPAN>操作符在两个类型兼容的时候执行转换，否则就返回<SPAN lang=EN-US>Nothing</SPAN>。</P>
<P>Class SomeClass(Of T)<BR><BR>&nbsp;&nbsp; Public Sub SomeMethod(ByVal value As T)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If TypeOf value Is Integer Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If TypeOf value Is LinkedList(Of Integer, String) Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim str As String = TryCast(value,String)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If (Not str Is Nothing) Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim list As LinkedList(Of Integer, String) = _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TryCast(value,LinkedList(Of <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer, String))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If (Not list Is Nothing) Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR>&nbsp;&nbsp; End Sub<BR>End Class</P>
<P><STRONG>对泛型类如何同步多线程访问？</STRONG></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通常来说，你不应该在一般类型参数上应用<SPAN lang=EN-US>Monitor</SPAN>。这是因为<SPAN lang=EN-US>Monitor</SPAN>只能用于引用类型。当你使用范型的时候，编译器不能预先判断你将会提供一个引用类型还是值类型的类型参数。在<SPAN lang=EN-US>C#</SPAN>中，编译器会允许你使用<SPAN lang=EN-US>lock</SPAN>语句，但是如果你提供了一个值类型作为类型参数，<SPAN lang=EN-US>lock</SPAN>语句在运行时将不起作用。在<SPAN lang=EN-US>Visual Basic</SPAN>中，编译器如果不能确定一般类型参数是一个引用类型，它将不允许在一般类型参数上面使用<SPAN lang=EN-US>SyncLock</SPAN>。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在<SPAN lang=EN-US>C#</SPAN>和<SPAN lang=EN-US>Visual Basic</SPAN>中，唯一你可以安全地将一般类型参数锁住的时候，是你将一般类型参数限制为引用类型，要么添加约束使其为引用类型，要么从一个基类中继承：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class MyClass&lt;T&gt; where T : class
{..}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass(Of T As Class)
   ...
End Class</PRE></SPAN>
<P>或者：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class SomeClass
{...}
public class MyClass&lt;T&gt; where T : SomeClass
{...}
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass
   ...
End Class
Public Class SomeClass(Of T As SomeClass)
   ...
End Class<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然而，通常对于同步来说，最好避免部分地锁住单独的成员变量，因为这会增加死锁的可能性。</P>
<P><STRONG>如何序列化泛型类？</STRONG></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包括了一般类型参数作为成员的范型类是可以被标记为序列化的：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>[Serializable]
public class MySerializableClass&lt;T&gt;
{
   T m_T;
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>&lt;Serializable()&gt; _
Public Class MySerializableClass(Of T)

   Dim m_T As T
End Class</PRE>
<P>[C++]</P><PRE class=code>generic &lt;typename T&gt;
[Serializable]
public ref class MyClass
{
   T m_T;
};<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是，在这种情况下，只有指定的类型参数可以被序列化时，范型类才可以被序列化。看下面的代码：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>public class SomeClass
{}
MySerializableClass&lt;SomeClass&gt; obj;
</PRE>
<P>[Visual Basic]</P><PRE class=code>Public Class SomeClass
End Class

Dim obj as MySerializableClass(Of SomeClass)
</PRE>
<P>[C++]</P><PRE class=code>public ref class SomeClass
{};
MyClass&lt;SomeClass ^&gt; ^obj;<BR></PRE></SPAN>
<P><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj</SPAN>不能被序列化，因为类型参数<SPAN lang=EN-US>SomeClass</SPAN>不可以被序列化。因此，<SPAN lang=EN-US>MySerializableClass&lt;T&gt;</SPAN>可能可以，也可能不可以被序列化，取决于使用的一般类型参数。这样可能导致在运行时丢失数据或者系统崩溃，因为客户应用程序可能不能够保持对象的状态。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前，<SPAN lang=EN-US>.NET</SPAN>没有提供将一般类型参数约束为可序列化的机制。解决办法是在运行时在使用这个类型之前单独进行检查，并且在任何损害发生之前马上中止使用。你可以把这个运行时的验证放在静态构造器里面：</P><SPAN lang=EN-US>
<P>[C#]</P><PRE class=code>[Serializable]
class MySerializableClass&lt;T&gt;
{
   T m_T;

   static MySerializableClass()   
   {
      ConstrainType(typeof(T));
   }
   static void ConstrainType(Type type)
   {
      bool serializable = type.IsSerializable;
      if(serializable == false)
      {
         string message = "The type " + type + " is not serializable";
         throw new InvalidOperationException(message);
      }
   }
}
</PRE>
<P>[Visual Basic]</P><PRE class=code>&lt;Serializable()&gt; _
Class SomeClass(Of T)
   Private m_T As T   

   Shared Sub New()
      ConstrainType(GetType(T))
   End Sub
   Private Shared Sub ConstrainType(ByVal t As Type)
      If Not t.IsSerializable Then
         Dim message As String = "The type " + t.ToString() + " is not 
                                                         serializable"
         Throw New InvalidOperationException(message)
      End If
   End Sub
End Class
</PRE>
<P>[C++]</P><PRE class=code>generic &lt;typename T&gt;
[Serializable]
ref class MyClass
{
   T m_T;
public:   
   static MyClass()   
   {
      ConstrainType(typeid&lt;T&gt;);
   }
private:
   static void ConstrainType(Type type)
   {
      bool serializable = type-&gt;IsSerializable;
      if(serializable == false)
      {
         String ^message = String::Concat("The type ", type-&gt;Name, 
            " is not serializable");
         throw gcnew SerializationException(message);
      }
   }
};<BR></PRE></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 静态构造器对每一个应用程序域的每一个类型只执行一次，而且是在类型第一次被请求实例化之前。尽管你有一些通过编程的方式来在运行时进行判断和执行检查，但是这种在静态构造器里面执行约束验证的技术，对任何无法在编译时进行检查的约束都适用。</P></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN><img src ="http://www.cnblogs.com/buaaytt/aggbug/270084.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44362/" target="_blank">硅谷财团欲收购雅虎 搜索业务将转卖给微软</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>.NET Framework 2.0 以及SDK可以下载了</title><link>http://www.cnblogs.com/buaaytt/archive/2005/10/28/263602.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Fri, 28 Oct 2005 01:58:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/10/28/263602.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/263602.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/10/28/263602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/263602.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/263602.html</trackback:ping><description><![CDATA[今天收到的邮件，.NET Framework 2.0和SDK的正式版提供下载了。下载地址在这里：<BR><A href="http://www.microsoft.com/downloads/results.aspx?productId=C9C8FCFB-BFF3-40CA-B59D-216F6850000A&amp;CategoryID=&amp;freetext=framework&amp;DisplayLang=en&amp;DisplayEnglishAlso=&amp;sortCriteria=date&amp;startDate=&amp;period=0&amp;type=&amp;nr=20">http://www.microsoft.com/downloads/results.aspx?productId=C9C8FCFB-BFF3-40CA-B59D-216F6850000A&amp;CategoryID=&amp;freetext=framework&amp;DisplayLang=en&amp;DisplayEnglishAlso=&amp;sortCriteria=date&amp;startDate=&amp;period=0&amp;type=&amp;nr=20</A><BR>有三个版本，x86，x64和IA64。Team Foundation Server的正式版还得等到明年初。 <img src ="http://www.cnblogs.com/buaaytt/aggbug/263602.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44361/" target="_blank">联想集团宣布全球裁员2500人</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>让窗体从初始时就保持最大化，并且不能改变窗体大小的完美解决方案</title><link>http://www.cnblogs.com/buaaytt/archive/2005/07/28/201976.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Thu, 28 Jul 2005 06:24:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/07/28/201976.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/201976.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/07/28/201976.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/201976.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/201976.html</trackback:ping><description><![CDATA[摘要: 我的要求就是让窗体从初始化的时候就最大化，并且用户不能改变窗体大小。最开始的想法是捕获窗体大小改变，即ReSize事件，然后在事件里面把窗体大小设置成初始时的大小。完整的Form.cs代码如下： usingSystem; usingSystem.Drawing; usingSystem.Collections; usingSystem.ComponentModel; usingSystem.Win&nbsp;&nbsp;<a href='http://www.cnblogs.com/buaaytt/archive/2005/07/28/201976.html'>阅读全文</a><img src ="http://www.cnblogs.com/buaaytt/aggbug/201976.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44360/" target="_blank">Intel公布初步财报 收入大减近四分之一</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>.NET执行==运算符时的转换处理</title><link>http://www.cnblogs.com/buaaytt/archive/2005/07/12/191469.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Tue, 12 Jul 2005 08:24:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/07/12/191469.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/191469.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/07/12/191469.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/191469.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/191469.html</trackback:ping><description><![CDATA[这个问题我最早发在CSDN论坛上，经过很多网友的热心帮助，最后我得出了一个结论。对不对我不知道，但是我有相当的自信是这样的，希望有人能告诉我吧。 <BR>例子代码如下： <BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;System; <BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;System.Collections; <BR><BR><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;value; <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;value) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(value&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">9</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ArgumentException(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;value; <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implicit</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">operator</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">(Digit&nbsp;d) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Conversion&nbsp;occured</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">)((</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)d.value&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>} <BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;app <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;Main() <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Digit&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;d; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;d); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>}</SPAN> </DIV></DIV>运行这段代码，结果是什么呢？ <BR>Conversion occured <BR>Conversion occured <BR>True <BR>刚开始我百思不得其解，因为d的值是5，而b的值是6，怎么会相等呢？后来在网友的帮助下，我得出了下面的看法： <BR>首先，==运算符两边的两个操作数都是值类型，所以==运算符只比较其值是否相等即可。 <BR>然后，也是最重要的一点就是，<SPAN style="COLOR: #ff0000">==</SPAN><STRONG style="COLOR: #ff0000">运算符两边的操作数的类型必须要一致，并且这个类型要重载了==运算符的实现。</STRONG>很显然，我自定义的Digit结构并没有重载==的实现。而据我推测，byte类型作为c#的基元类型，是实现了==运算符的。因此，在这里，CLR在执行的时候会将Digit转换到byte类型再比较，而转换的结果比转换前的值要大1，所以两者都是6了（注意转换后d的值还是5，但是==比较的是b和将d转换后的返回值）。结果就是True了。这也可以解释为什么会出现两个&#8220;Conversion occured&#8221;了。因为进行了两次隐式转换，为变量b赋值时进行了一次，==比较的时候又进行了一次。通过单步执行可以更清楚地看到这个过程。<BR><BR>为了更加深入研究这个例子，并且证明我前面的猜测：<SPAN style="COLOR: #ff0000"><SPAN style="COLOR: #ff0000"><SPAN style="COLOR: #ff0000">==</SPAN><STRONG>运算符两边的操作数的类型必须要一致，并且这个类型要重载了==运算符的实现。</STRONG></SPAN></SPAN>我把代码做了一点小的修改，Main方法替换为下面的代码：<BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Digit&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Digit&nbsp;d2&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #000000">6</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(d&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;d2);</SPAN></DIV></DIV>按照我的猜测，虽然==运算符两边都是Digit，而Digit又没有重载==运算符，但这时并不是不能比较，因为我们在Digit结构中定义了从Digit到byte的隐式转换。所以在执行到==的时候，会分别将d和d2转换到byte类型，再进行比较，即比较6和7了，最后结果当然就是：<BR>Conversion occured<BR>Conversion occured<BR>False<BR>如果我们把Digit定义中到byte的隐式转换注释掉，那么c#编译器就会报如下的错误：<BR>Operator '==' cannot be applied to operands of type 'Digit' and 'Digit'<BR>因为Digit没有重载==运算符，编译器又找不到存在的任何转换（包括隐式的和显式的），所以就会报错。<BR><BR>这个例子告诉我们，如果我们自己定义了结构，而且需要对该结构类型的对象进行==运算，那么我们就要自己定义==运算符，否则结果就可能不是我们预期的那样了：<BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;System;<BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;System.Collections;<BR><BR><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;value;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;value)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(value&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">9</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ArgumentException();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;value;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implicit</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">operator</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">(Digit&nbsp;d)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Conversion&nbsp;occured</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">)((</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)d.value&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">operator</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;b,&nbsp;Digit&nbsp;d)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;d.value;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">operator</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;b,&nbsp;Digit&nbsp;d)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;app<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;Main()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Digit&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Digit(</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;d;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</SPAN></DIV></DIV>这样，由于我们实现了在byte和Digit类型之间的==运算符，所以就不会像前面那样进行类型转换了，结果也当然是我们预期的那样了：<BR>Conversion occured<BR>False <img src ="http://www.cnblogs.com/buaaytt/aggbug/191469.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44359/" target="_blank">Facebook用户1.5亿 堪称全球第八人口大国</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>我觉得VS2005的Refactor应该提供泛型到非泛型之间的转换</title><link>http://www.cnblogs.com/buaaytt/archive/2005/06/24/180265.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Fri, 24 Jun 2005 04:25:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/06/24/180265.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/180265.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/06/24/180265.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/180265.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/180265.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如当前有一个类是泛型，现在我不想要泛型了，而且改变之后不会对其他代码产生很大的影响，这时应该可以通过Refactor来帮助把代码中的&lt;&gt;以及相关部分去掉，当然之前会要求你输入一个特定类型来取代泛型中的一般类型。<BR>同样，如果想把当前某个类型改成泛型，Refactor也应该可以做到，只需要用一般类型替换掉当前的特定类型就可以了。<img src ="http://www.cnblogs.com/buaaytt/aggbug/180265.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44356/" target="_blank">国内3G牌照正式发放 三运营商分获三张牌照</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>MSDN中文网站关于翻译有很严重的问题</title><link>http://www.cnblogs.com/buaaytt/archive/2005/06/21/178406.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Tue, 21 Jun 2005 07:09:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/06/21/178406.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/178406.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/06/21/178406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/178406.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/178406.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 就是内容翻译得尚可，但是代码简直是没法看。我每次看中文翻译的文章的时候遇到代码，都要转到相应英文页面去看代码。不知道为什么中文翻译里的代码和原文里的代码相差那么大，很多时候都会严重影响阅读。 看看这篇MSDN翻译里面的代码块就能理解了：<A href="http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx">http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx</A> <img src ="http://www.cnblogs.com/buaaytt/aggbug/178406.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44355/" target="_blank">传今年Windows Live Hotmail将启动POP3访问</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>使用System.StringSplitOptions去除待拆分字符串中的空项</title><link>http://www.cnblogs.com/buaaytt/archive/2005/06/17/176119.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Fri, 17 Jun 2005 04:55:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/06/17/176119.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/176119.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/06/17/176119.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/176119.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/176119.html</trackback:ping><description><![CDATA[很简单的东西，今天学会了，就记下来了。<BR><BR>当我们使用某个字符来将一个字符串拆分到字符串数组中的时候，如果待拆分的字符串中有空项，也就是 "" 的时候，在结果数组中也会出现。如果不想将空项包含在结果数组中，就可以使用.NET 2.0的一个新的枚举StringSplitOptions来设置。具体代码如下：<BR><BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">0,1,2,</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG id=Codehighlighter1_56_60_Open_Image onclick="this.style.display='none'; Codehighlighter1_56_60_Open_Text.style.display='none'; Codehighlighter1_56_60_Closed_Image.style.display='inline'; Codehighlighter1_56_60_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_56_60_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_60_Closed_Text.style.display='none'; Codehighlighter1_56_60_Open_Image.style.display='inline'; Codehighlighter1_56_60_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;[]&nbsp;res&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;s.Split(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;[]</SPAN><SPAN id=Codehighlighter1_56_60_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_56_60_Open_Text><SPAN style="COLOR: #000000">{</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">}</SPAN></SPAN><SPAN style="COLOR: #000000">,&nbsp;StringSplitOptions.RemoveEmptyEntries);<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;str&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&nbsp;res&nbsp;)<BR><IMG id=Codehighlighter1_133_159_Open_Image onclick="this.style.display='none'; Codehighlighter1_133_159_Open_Text.style.display='none'; Codehighlighter1_133_159_Closed_Image.style.display='inline'; Codehighlighter1_133_159_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_133_159_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_133_159_Closed_Text.style.display='none'; Codehighlighter1_133_159_Open_Image.style.display='inline'; Codehighlighter1_133_159_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_133_159_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_133_159_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>Console.WriteLine(str);<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>Console.WriteLine(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Total:{0}</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;res.Length);<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>Console.ReadLine();</SPAN></DIV></DIV>
<P><BR>结果就是：<BR>0<BR>1<BR>2<BR>Total:3<BR><BR>如果改成StringSplitOptions.None或者没有这个参数（默认也为None），那么结果就是：<BR>0<BR>1<BR>2</P>
<P>Total:4</P><img src ="http://www.cnblogs.com/buaaytt/aggbug/176119.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44353/" target="_blank">iTunes音乐商店全面放弃DRM版权保护</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Remoting中在客户端使用自定义的Sponsor</title><link>http://www.cnblogs.com/buaaytt/archive/2005/02/23/107935.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Wed, 23 Feb 2005 04:08:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/02/23/107935.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/107935.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/02/23/107935.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/107935.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/107935.html</trackback:ping><description><![CDATA[摘要: 很是郁闷，本来写好了，修改提交了几次又没了一大半，只好简单地重新写一点了。 我说话比较喜欢简洁，直接看代码吧（例子根据《Advanced .NET Remoting》一书而来）： Server端： Using&#160;directives#region&#160;Using&#160;directives  using&#160;System; using&#160;System.Collect&nbsp;&nbsp;<a href='http://www.cnblogs.com/buaaytt/archive/2005/02/23/107935.html'>阅读全文</a><img src ="http://www.cnblogs.com/buaaytt/aggbug/107935.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44352/" target="_blank">令人失望 本届Macworld Keynote内容总结</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>SoapSuds工具使用初探</title><link>http://www.cnblogs.com/buaaytt/archive/2005/01/05/106974.html</link><dc:creator>buaaytt</dc:creator><author>buaaytt</author><pubDate>Tue, 04 Jan 2005 19:45:00 GMT</pubDate><guid>http://www.cnblogs.com/buaaytt/archive/2005/01/05/106974.html</guid><wfw:comment>http://www.cnblogs.com/buaaytt/comments/106974.html</wfw:comment><comments>http://www.cnblogs.com/buaaytt/archive/2005/01/05/106974.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/buaaytt/comments/commentRss/106974.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/buaaytt/services/trackbacks/106974.html</trackback:ping><description><![CDATA[<p>SoapSuds工具的作用在此就不多说了。简单地说，就是产生程序集的元数据，而这主要使用在Remoting架构中</p>
<p>。在Remoting中，为了达到客户端和服务端对远程对象元数据的分离，使用SoapSuds工具产生远程对象的元数</p>
<p>据，这样在客户端就不用引用远程对象的程序集了。
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; 下面列举了几种使用SoapSuds的例子，其中有几个有趣的现象，我也会描述出来：
<br/>1、对SAO对象：
<br/>Server端采用通常的实现代码：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcpChannel chan = new TcpChannel(9999);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ChannelServices.RegisterChannel(chan);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObj), </p>
<p>&quot;RemoteObject&quot;, WellKnownObjectMode.Singleton);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;RemoteObject is Registered.&quot;);
</p>
<p>Client端也采用通常的实现代码：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemoteObj obj = (RemoteObj)Activator.GetObject(typeof(RemoteObj), 
</p>
<p>&quot;tcp://localhost:9999/RemoteObject&quot;);</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(obj.test());</p>
<p>远程对象RemoteObject的功能很简单，返回字符串：
<br/>public class RemoteObj : MarshalByRefObject
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public RemoteObj()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { }
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public RemoteObj(string a)
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { }
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public string test()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return &quot;test&quot;;
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
<br/>&#160;&#160;&#160; }
</p>
<p>现在代码完成了。首先编译RemoteObject的代码。然后打开.Net Framework Command Prompt，这里我们假定编</p>
<p>译后的程序集就在bin\debug目录下。用cd命令进入到该目录，然后运行如下的命令：
<br/>soapsuds -ia:RemoteObject -oa:meta.dll
<br/>-ia参数表明输入程序集是RemoteObject，也就是说要从这个程序集中提取元数据。注意这里不能加任何后缀如
</p>
<p>.dll，.exe，否则会出错
<br/>-oa参数表明输出程序集会存放在该目录下的meta.dll文件中，也就是说这个程序集中就是提取出来的元数据了
<br/>好了，现在在Client项目里面加上对这个meta.dll的引用，然后分别编译Client和Server，顺序无所谓。
<br/>最后执行，先执行Server.exe，看到输出&#8220;RemoteObject is Registered.&#8221;后再执行Client.exe，如果看到输
</p>
<p>出了&#8220;test&#8221;，那么说明成功了。
<br/>对于SAO对象，是否加上-nowp选项对结果没有什么影响，至少我使用的时候是这样。如果有谁知道更多信息，
</p>
<p>请告诉我：）
<br/>2、对CAO对象
</p>
<p>Server端代码如下：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcpChannel chan = new TcpChannel(9999);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ChannelServices.RegisterChannel(chan);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.ApplicationName = &quot;RemoteObject&quot;;
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.RegisterActivatedServiceType(typeof(RemoteObj));
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;RemoteObject is Registered.&quot;);
<br/>Client端代码也要做相应修改，我们采取如下的方式（当然还有其它方式）：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.RegisterActivatedClientType(typeof(RemoteObj), 
</p>
<p>&quot;tcp://localhost:9999/RemoteObject&quot;);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemoteObj obj = new RemoteObj();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(obj.test());
<br/>远程对象，我们还是首先使用上面产生的那个程序集，也就是WrappedProxy。
</p>
<p>好了，现在还是按照刚才那样，依次启动Server和Client，你可以看到预料中的&#8220;test&#8221;输出到了客户端。
<br/>到此为止，基本的SoapSuds使用已经结束了。下面说些题外话：
<br/>1、对于CAO，是否加上-nowp选项对结果的一个小小的影响
</p>
<p>我们在客户端代码中注释掉这一行：
<br/>RemotingConfiguration.RegisterActivatedClientType(typeof(RemoteObj), 
</p>
<p>&quot;tcp://localhost:9999/RemoteObject&quot;);
<br/>也就是去掉在客户端进行注册这一过程。现在如果我们使用的是WrappedProxy，也就是用下面的命令产生的程
</p>
<p>序集：
<br/>soapsuds -ia:remoteobject -oa:meta.dll
<br/>这时我们启动Client会得到如下的输出：
<br/>System.NullReferenceException: Object reference not set to an instance of an object.
<br/>我们可以通过查看产生的源代码来分析，用下面的命令产生元数据的源代码：
<br/>soapsuds -ia:remoteobject -gc
<br/>这里我们使用-gc选项，而不是-oa选项，意思是产生源代码，而不是程序集。我们打开这个产生的源代码文件
</p>
<p>，可以看到下面的代码（我省略了一些附加的跟我要说明的无关的信息）：
<br/>public class RemoteObj : System.Runtime.Remoting.Services.RemotingClientProxy
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public RemoteObj()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
</p>
<p>System.Runtime.Remoting.SoapServices.PreLoad(typeof(RemoteObject.Properties.Settings));
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public Object RemotingReference
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get{return(_tp);}
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public String test()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return ((RemoteObj) _tp).test();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160; }
<br/>对此我的理解是：这个RemoteObj类是从System.Runtime.Remoting.Services.RemotingClientProxy继承下来的
</p>
<p>，因此调用new操作符的时候会试图在服务端产生远程对象的新实例。但是因为我们根本没有在客户端注册，所</p>
<p>以客户端不知道服务端在哪里，也就不知道在哪里创建远程对象了，所以使用new操作符产生的对象就是一个空</p>
<p>引用null，从而导致出现这个异常。</p>
<p>而如果使用的是NonWrappedProxy，也就是用下面的命令产生的程序集：
<br/>soapsuds -ia:remoteobject -oa:meta.dll -nowp
<br/>我们不改变Client代码重新编译Client后运行，会发现没有异常，而只是输出了一个空行。我们同样产生源代
</p>
<p>码来分析：
<br/>soapsuds -ia:remoteobject -gc -nowp
<br/>观察结果：
<br/>&#160;public class RemoteObj : System.MarshalByRefObject
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public String test()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return((String) (Object) null);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160; }
<br/>可以看到，现在RemoteObj类是直接从MarshalByRefObject类继承。所以我猜测调用test方法时会先尝试创建远
</p>
<p>程对象的实例，但是由于没有在客户端注册，因此无法创建，这时就会调用本地的return((String) (Object) </p>
<p>null)。所以就返回了null，从而可以在Console中看到输出了一个空行。
<br/>这是我发现的第一个有趣的现象。
<br/>2、如果我们将Server的实现和远程对象的实现放在一个程序集中（虽然实际工作中这种情况比较少见），也有
</p>
<p>一些要注意的地方。
<br/>我们将Server.cs文件改成如下这样：
<br/>class SomeRemoteObject : MarshalByRefObject
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void doSomething()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;SomeRemoteObject.doSomething() called&quot;);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
<br/>&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160; class ServerStartup
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; static void Main(string[] args)
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcpChannel chnl = new TcpChannel(1234);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ChannelServices.RegisterChannel(chnl);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.RegisterWellKnownServiceType(
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; typeof(SomeRemoteObject),
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;SomeRemoteObject&quot;,
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; WellKnownObjectMode.SingleCall);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;ServerStartup.Main(): Server started&quot;);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadLine();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
<br/>&#160;&#160;&#160; }
<br/>客户端使用如下的代码：
<br/>static void Main(string[] args)
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SomeRemoteObject obj = (SomeRemoteObject)Activator.GetObject(
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; typeof(SomeRemoteObject),
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;tcp://localhost:1234/SomeRemoteObject&quot;);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; obj.doSomething();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadLine();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
<br/>现在该如何产生元数据程序集呢？
<br/>如果我们还是按照先前的思路，用如下的命令：
<br/>soapsuds -ia:server -oa:meta.dll
<br/>那么我们在客户端添加对meta.dll的引用后，编译会出现如下的错误：
<br/>The type or namespace name &#39;SomeRemoteObject&#39; could not be found (are you missing a using 
</p>
<p>directive or an assembly reference?) 
<br/>为什么会这样呢？我们还是产生源代码来看看
<br/>soapsuds -ia:server -gc
<br/>结果里竟然没有我们的SomeRemoteObject类的代码（为什么会这样？我也不知道）。那么我们是不是就没有办
</p>
<p>法了呢？当然不是，别忘了SoapSuds还有个参数-types，可以指定产生哪个类的元数据。所以我们用下面的命</p>
<p>令来产生元数据程序集：
<br/>soapsuds -types:Server.SomeRemoteObject,Server -oa:meta.dll
<br/>-types后面紧接的是要产生元数据的类的完整名称，包括命名空间，而且大小写也要一致，逗号后面跟上程序
</p>
<p>集的名称，大小写无所谓，而且也不能包含.dll或.exe后缀。
<br/>然后我们将这个引用添加到客户端，再编译。运行，可以看到在服务端输出了&#8220;SomeRemoteObject.doSomethin
</p>
<p>g() called&#8221;这一行，成功了。
<br/>我们仍然可以观察产生的源代码来看看：
<br/>soapsuds -types:Server.SomeRemoteObject,Server -gc
<br/>结果如下：
<br/>public class SomeRemoteObject : System.Runtime.Remoting.Services.RemotingClientProxy
<br/>&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public SomeRemoteObject()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public Object RemotingReference
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get{return(_tp);}
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void doSomething()
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ((SomeRemoteObject) _tp).doSomething();
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }
</p>
<p>&#160;&#160;&#160; }
<br/>3、还是当Server的实现和远程对象的实现在一个程序集中的情况，这次我们使用Http通道，你会发现有一些不
</p>
<p>同的哦。
<br/>对Server代码做小小修改：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HttpChannel chnl = new HttpChannel(1234);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ChannelServices.RegisterChannel(chnl);
</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RemotingConfiguration.RegisterWellKnownServiceType(
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; typeof(SomeRemoteObject),
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;SomeRemoteObject.soap&quot;,
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; WellKnownObjectMode.SingleCall);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadLine();
<br/>相应的Client代码也要小小修改：
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SomeRemoteObject obj = (SomeRemoteObject)Activator.GetObject(
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; typeof(SomeRemoteObject),
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;<a href="http://localhost:1234/SomeRemoteObject.soap"><font color="#0000ff">http://localhost:1234/SomeRemoteObject.soap</font></a>&quot;);
<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; obj.doSomething();
<br/>我们除了上面2中所介绍的方法之外，还可以用另一种方法来产生元数据——就是SoapSuds的-url选项。
<br/>我们用下面的命令来产生元数据程序集：
<br/>soapsuds -url:http://localhost:1234/SomeRemoteObject.soap?wsdl -oa:meta.dll
<br/>注意写法：-url后面跟上的是远程对象的url，注意在SomeRemoteObject.soap后面加上了?wsdl（为什么要这样
</p>
<p>写？天晓得）。
<br/>结果如下：
<br/>Error: Unable to retrieve schema from url: <a href="http://localhost:1234/SomeRemoteObjec"><font color="#0000ff">http://localhost:1234/SomeRemoteObjec</font></a>
<br/>t.soap?wsdl, Unable to connect to the remote server, 不能做任何连接，因为目标机
<br/>器积极地拒绝它。
<br/>怎么出错了？从错误提示我们可以猜测到，是因为没有启动Server。原来SoapSuds在提取元数据的时候需要找
</p>
<p>到远程对象。因为我们用的是-url参数，所以SoapSuds会从这个URL中去提取元数据，但是我们都没有启动Serv</p>
<p>er，自然SoapSuds找不到远程对象。
<br/>好了，我们启动Server后，再执行SoapSuds，OK。然后我们在客户端添加对meta.dll的引用，编译，执行Clien
</p>
<p>t，一切都按照我们预想的出来了。</p>
<p>以上都是我在.Net Framework 2.0 beta环境下实际操作后的结果，当然可能会有不正确的地方。希望高人能够</p>
<p>不吝赐教。
<br/>另外，<A href="http://www.cnblogs.com/rickie/archive/2004/10/08/49725.html"><font color="#0000ff">Rickie</font></a>和<A href="http://www.cnblogs.com/wayfarer/Messages/2005/01/17/93102.html"><font color="#0000ff">Wayfarer</font></a>的两篇blog中叙述了SoapSuds工具的一些不足。
<br/>我个人觉得主要的不足就是不能提取出带参数的构造函数，我们只能通过产生源代码，然后手动去修改
</p><img src ="http://www.cnblogs.com/buaaytt/aggbug/106974.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/><a href="http://job.cnblogs.com/offer/302/" target="_blank">盛大招聘.Net开发工程师 </a><br/><a href="http://www.hjbook.net/product/4041/" target="_blank">经典好书：.NET框架程序设计（修订版）</a><br/>新闻：<a href="http://news.cnblogs.com/n/44351/" target="_blank">百度阿拉丁计划 - 看上去很美</a><br/>导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://job.cnblogs.com/" target="_blank">招聘</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>