<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://interop123.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-CHS"><title type="html">小崔爱自由</title><subtitle type="html" /><id>http://interop123.com/blogs/xcui/atom.aspx</id><link rel="alternate" type="text/html" href="http://interop123.com/blogs/xcui/default.aspx" /><link rel="self" type="application/atom+xml" href="http://interop123.com/blogs/xcui/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61120.2">Community Server</generator><updated>2009-05-16T03:32:00Z</updated><entry><title>C#4.0新特性对.NET互操作的影响</title><link rel="alternate" type="text/html" href="http://interop123.com/blogs/xcui/archive/2009/05/16/c-4-0-net.aspx" /><id>http://interop123.com/blogs/xcui/archive/2009/05/16/c-4-0-net.aspx</id><published>2009-05-15T19:32:00Z</published><updated>2009-05-15T19:32:00Z</updated><content type="html">&lt;P&gt;说道C#的新版本对.NET互操作的影响就不得不先说一下C#4.0的新特性。&lt;/P&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;Dynamically Typed Objects.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;Optional and Named Parameters.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;Improved COM Interoperability.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;Safe Co- and Contra-variance.&lt;/FONT&gt;&lt;/LI&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;这其中第2、3条都和互操作有关系。第2点的可选参数和命名参数并不是什么新概念了。主要在于编译器的支持。像VB.NET早就支持可选参数了。这几年C#社区对这个特性的呼声太高了，看来终于起作用了。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;FONT size=3&gt;&lt;U&gt;一、可选参数&lt;/U&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;有很多COM方法都接受可选参数。在调用此类方法时，可以根据具体需要为可选参数传递指定的值，或者忽略此参数而使用该参数的默认值。在使用托管代码调用COM方法时，根据不同的.NET语言，调用的复杂度也有所差异。由于Visual Basic .NET本身就支持可选参数（&lt;STRONG&gt;&lt;EM&gt;Optional&lt;/EM&gt;&lt;/STRONG&gt;关键字），它能够以可选方式使用该参数。但如果使用C#，情况就会大为不同。由于C#不支持可选参数，因此就必须为方法中的每个参数传递值，比如可以为可选参数传递&lt;STRONG&gt;&lt;EM&gt;System.Type.Missing&lt;/EM&gt;&lt;/STRONG&gt;以设置该参数的默认值。由于必须为所有的可选参数传递值，因此使用C#调用带有可选参数的COM方法，就不如Visual Basic .NET方便和灵活。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;使用过Office PIA的朋友，在操作word文档时一定遇到过下面的例子：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;object&lt;/SPAN&gt; fileName = &lt;SPAN style="COLOR:#006080;"&gt;"Test.docx"&lt;/SPAN&gt;;&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;object&lt;/SPAN&gt; missing&amp;nbsp; = System.Reflection.Missing.Value;&lt;BR&gt;doc.SaveAs(&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; fileName,&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing,&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing,&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing,&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing,&lt;BR&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing, &lt;SPAN style="COLOR:#0000ff;"&gt;ref&lt;/SPAN&gt; missing);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;为了调用SaveAs方法，你不得不为填写全部不必要的参数。这就是由于老的C#版本不支持可选参数的原因。&lt;/FONT&gt;&lt;BR&gt;在C#4.0出现后，情况就大不一样了。比如上面的代码可以写成：&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;doc.SaveAs(&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;"Test.docx"&lt;FONT color=#000000&gt;);&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;注：&lt;A href="http://www.china-pub.com/45607" target=_blank&gt;《精通.NET互操作》&lt;/A&gt;一书特别在第6.4.7节“传递可选参数”中，介绍了如何使用Optional和DefaultParameterValue属性使得由C#构造并导出的COM方法支持可选参数。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;STRONG&gt;&lt;FONT size=3&gt;&lt;U&gt;二、对COM互操作的改进支持&lt;/U&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;新特性的第3点提到了特别针对COM互操作的改进。这包括：&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;1.在同一进程中host多个版本的CLR。这样可以为托管COM组建选择它所需（编译时）的运行时版本。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;2. 不再必须使用PIA（Primary Interop Assembly）于COM组建交互。在过去，当你发布一个COM组建时，微软建议你随该组建发布一个PIA。这个附带的程序集PIA用来被托管应用程序客户端引用。在.NET Framework 4.0中PIA将被弱化。C#和VB编译器会判断你的程序具体使用了哪一部分COM API，并只把这部分包装成IA（互操作程序集），直接加入到你自己的应用程序集里面。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;3. 重定义QueryInterface。你可以使用&lt;SPAN&gt;&lt;A id=ctl00_mainContentContainer_ctl51 href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustomqueryinterface(VS.100).aspx"&gt;&lt;FONT color=#0033cc&gt;System.Runtime.InteropServices&lt;SPAN class=cs&gt;.&lt;/SPAN&gt;ICustomQueryInterface&lt;/FONT&gt;&lt;/A&gt;接口自定义由托管代码实现的&lt;A id=ctl00_mainContentContainer_ctl53 href="http://go.microsoft.com/fwlink/?LinkID=144867"&gt;&lt;FONT color=#0033cc&gt;IUnknown::QueryInterface&lt;/FONT&gt;&lt;/A&gt;方法。应用程序可以用它返回特定的接口。&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000 size=3&gt;&lt;SPAN&gt;&lt;STRONG&gt;&lt;U&gt;三、.NET Framework 4.0对线程的新特性&lt;/U&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;最后，.NET Framework 4.0在线程类Thread中加入了Yield()方法。它可以使调用线程将当前CPU的资源让给另一个准备好的线程。操作系统负责选择新线程。放弃只会对处理调用线程的CPU产生效果，操作系统不会切换执行到另一CPU，即使那个CPU正处于空闲状态。如果当前CPU上没有其他可执行的线程，Thread.Yield()方法的调用将返回false。&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;这个Thread.Yield()的方法相当于使用pinvoke调用Win32 API &lt;STRONG&gt;SwitchToThread&lt;/STRONG&gt;。有了该新方法，就可以避免使用平台调用引入的额外开销，以及解决平台调用不能处理自定义线程行为的问题。&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000 size=3&gt;&lt;SPAN&gt;&lt;STRONG&gt;&lt;U&gt;参考：&lt;/U&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;1. &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;&lt;A href="http://www.china-pub.com/45607" target=_blank&gt;【书】《精通.NET互操作：P/Invoke，C++ Interop和COM Interop》&lt;/A&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;2. &lt;A href="http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx" target=_blank&gt;What's New in the .NET Framework 4&lt;/A&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 face="Courier New"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;&lt;SPAN style="COLOR:#006080;"&gt;&lt;FONT color=#000000&gt;&lt;SPAN&gt;3. &lt;A href="http://interop123.com/forums/thread/35.aspx" target=_blank&gt;【视频】Managed and Native Code Interoperability: Best Practices&lt;/A&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;img src="http://interop123.com/aggbug.aspx?PostID=37" width="1" height="1"&gt;</content><author><name>xcui</name><uri>http://interop123.com/members/xcui.aspx</uri></author><category term="Interop" scheme="http://interop123.com/blogs/xcui/archive/tags/Interop/default.aspx" /><category term="COM Interop" scheme="http://interop123.com/blogs/xcui/archive/tags/COM+Interop/default.aspx" /><category term="C# 4.0" scheme="http://interop123.com/blogs/xcui/archive/tags/C_2300_+4.0/default.aspx" /><category term=".NET" scheme="http://interop123.com/blogs/xcui/archive/tags/.NET/default.aspx" /></entry></feed>
