<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://interop123.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>小崔爱自由</title><link>http://interop123.com/blogs/xcui/default.aspx</link><description /><dc:language>zh-CHS</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>C#4.0新特性对.NET互操作的影响</title><link>http://interop123.com/blogs/xcui/archive/2009/05/16/c-4-0-net.aspx</link><pubDate>Fri, 15 May 2009 19:32:00 GMT</pubDate><guid isPermaLink="false">b1280fd9-26a1-4865-a2de-26bd23f581dd:37</guid><dc:creator>小崔爱自由</dc:creator><slash:comments>0</slash:comments><comments>http://interop123.com/blogs/xcui/comments/37.aspx</comments><wfw:commentRss>http://interop123.com/blogs/xcui/commentrss.aspx?PostID=37</wfw:commentRss><description>&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;</description><category domain="http://interop123.com/blogs/xcui/archive/tags/Interop/default.aspx">Interop</category><category domain="http://interop123.com/blogs/xcui/archive/tags/COM+Interop/default.aspx">COM Interop</category><category domain="http://interop123.com/blogs/xcui/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://interop123.com/blogs/xcui/archive/tags/.NET/default.aspx">.NET</category></item></channel></rss>