<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Sam Ng's Blog : Interop</title><link>http://blogs.msdn.com/samng/archive/tags/Interop/default.aspx</link><description>Tags: Interop</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Com interop in C# 4.0: Indexed Properties</title><link>http://blogs.msdn.com/samng/archive/2009/11/03/com-interop-in-c-4-0-indexed-properties.aspx</link><pubDate>Tue, 03 Nov 2009 16:52:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9916833</guid><dc:creator>samng</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/samng/comments/9916833.aspx</comments><wfw:commentRss>http://blogs.msdn.com/samng/commentrss.aspx?PostID=9916833</wfw:commentRss><description>&lt;p&gt;One of the things I love about my job is that I get to make people happy. How do I do that? By giving them what they want of course! One of the things I don’t like so much about my job is going back on a decision that we made before, and having to revert some of the behavior. Well, &lt;a href="http://blogs.msdn.com/samng/archive/2009/06/16/com-interop-in-c-4-0.aspx"&gt;we’ve been talking about COM interop in C# 4.0&lt;/a&gt;, and are now in the thick of things. Today we’ll chat about a feature which many people have asked for in the past, but we’ve stayed away from until now – Indexed Properties.&lt;/p&gt;  &lt;h5&gt;What are indexed properties?&lt;/h5&gt;  &lt;p&gt;Great question! Indexed properties are exactly what they sound like – they’re properties that you can index into. In a sense, you can think of them as an atomic form of accessing a property, and then indexing off of the return value of the property. The following is an example of an indexed property access:&lt;/p&gt;  &lt;pre class="code"&gt;myObject.MyIndexedProperty[index];&lt;/pre&gt;

&lt;p&gt;Indexed properties under the covers are simply accessor methods and a property, much like regular properties, except that both the accessor methods and the property have extra parameters. Or another way to look at them is that they’re just regular indexers except with a name other than “Item”.&lt;/p&gt;

&lt;h5&gt;Why didn’t we add them earlier?&lt;/h5&gt;

&lt;p&gt;We didn’t add these guys earlier because we felt that this wasn’t the design principle that we wanted people to conform to. We believed (and still do!) that the correct meaning of our sample statement is “I’m accessing a property named P off of my type C. Once I’ve got a resulting value, I’m going to index off of it.”&lt;/p&gt;

&lt;h5&gt;&lt;/h5&gt;

&lt;h5&gt;So what’s the issue here?&lt;/h5&gt;

&lt;p&gt;The issue is that while we firmly believe that the current C# semantics are the right ones, we unfortunately have a large legacy set of libraries that have shipped with indexed properties – COM. &lt;/p&gt;

&lt;p&gt;We’ve applied the same philosophy to indexed properties that we discussed last time, and have put support in the language for them only in COM interop scenarios. &lt;/p&gt;

&lt;p&gt;On the declaration front, we have &lt;em&gt;not&lt;/em&gt; provided the ability to declare these guys. Since true COM libraries are created via tlbimp, these should never be created in C#. &lt;/p&gt;

&lt;p&gt;On the consumption front, the compiler will now import anything that looks like an incdexed property off of a COM type (ie a type with the tdImport flag), and allow it to be used via the named indexer syntax. Keen readers will note that the above sentence reads “the compiler will allow the indexed property &lt;em&gt;to be consumed via named indexer syntax”&lt;/em&gt;, and not “the compiler will &lt;em&gt;treat the indexed property as a property”&lt;/em&gt;. The difference being, of course, that true properties cannot be accessed via their accessor methods directly, but in order to maintain backwards compatibility, accessing the accessor of an indexed property directly must still be allowed.&lt;/p&gt;

&lt;h5&gt;Overload resolution&lt;/h5&gt;

&lt;p&gt;Let me go into a bit more depth and using our sample statement again describe the changes that we’ve made to overload resolution to allow these guys to be bound. &lt;/p&gt;

&lt;p&gt;The first thing the compiler does when it sees the statement is it binds the left side of the dot, and resolves myObject to its type, say MyType. Once it’s done that, it goes and looks up everything with the name MyIndexedProperty on MyType. &lt;/p&gt;

&lt;p&gt;In order to maintain backwards compatibility, if the compiler finds something other than an indexed property, it will go ahead and bind to whatever it found. Indexed properties in that sense are like extension methods – they only apply when all the normal binding steps have failed.&amp;#160; Notice however, that this happens on name lookup time, and not on the indexer argument resolution time. More explicitly, if the compiler found a regular property named MyIndexedProperty of type C, and C does not have an indexer on it, the compiler &lt;em&gt;will not&lt;/em&gt; bind to an indexed property named MyIndexedProperty. It will provide the same error you would have gotten with the C# 3.0 compiler – namely that there is not an indexer on the type C. &lt;/p&gt;

&lt;p&gt;Once the compiler has verified that “normal” binding (ie binding that we would have done without considering indexed properties) has failed, it then checks the type MyType to see if it’s a ComImport type. If it is, then the compiler looks at all available indexed properties and performs the regular overload resolution algorithm on the indexed property candidates much like it would for regular indexers. It simply treats the candidates as indexers with names.&lt;/p&gt;

&lt;h5&gt;IL Generation&lt;/h5&gt;

&lt;p&gt;Because we bind the indexed property like named indexers, we generate IL as if we were calling an indexer that has a name – namely, we call the get_Index method, but with the name of the indexed property.&lt;/p&gt;

&lt;p&gt;In our example, the IL we generate would simply be a call to myObject.get_MyIndexedProperty(index), which is exactly what users had to write in previous versions of the language. Because indexed properties (and indexers in general) are really just syntactic sugar for calling accessor methods, nothing special needs to happen here both from a compiler standpoint and a runtime standpoint.&lt;/p&gt;

&lt;h5&gt;So really, these guys are just sugar?&lt;/h5&gt;

&lt;p&gt;Yep. These guys are just nice syntactic sugar. The great thing about sugar though, is that it really is sweet. Let me just leave you with a comparison of a common scenario.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// C# 3.0
&lt;/span&gt;myObject.set_MyIndexedProperty(myObject.get_MyIndexedProperty(index) + 1);
&lt;span style="color: green"&gt;// C# 4.0
&lt;/span&gt;myObject.MyIndexedProperty[index]++;&lt;/pre&gt;

&lt;p&gt;The indexed property syntax is much nicer isn’t it? If you’re a COM programmer, I’m absolutely positive that you’ll agree!&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblogs.msdn.com%2fsamng%2farchive%2f2009%2f11%2f03%2fcom-interop-in-c-4-0-indexed-properties.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblogs.msdn.com%2fsamng%2farchive%2f2009%2f11%2f03%2fcom-interop-in-c-4-0-indexed-properties.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9916833" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/samng/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category><category domain="http://blogs.msdn.com/samng/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/samng/archive/tags/COM/default.aspx">COM</category><category domain="http://blogs.msdn.com/samng/archive/tags/Interop/default.aspx">Interop</category><category domain="http://blogs.msdn.com/samng/archive/tags/Indexed+Properties/default.aspx">Indexed Properties</category></item><item><title>COM Interop in C# 4.0</title><link>http://blogs.msdn.com/samng/archive/2009/06/16/com-interop-in-c-4-0.aspx</link><pubDate>Tue, 16 Jun 2009 23:25:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9763363</guid><dc:creator>samng</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/samng/comments/9763363.aspx</comments><wfw:commentRss>http://blogs.msdn.com/samng/commentrss.aspx?PostID=9763363</wfw:commentRss><description>&lt;p&gt;Wow, it’s been a while since I’ve last posted! Don’t worry, I’m still alive and kickin’, and we’re still workin’ on cool stuff for y’all to use.&lt;/p&gt;  &lt;p&gt;Let’s take a bit of a recap of how far we’ve come. We’ve chatted about &lt;a href="http://blogs.msdn.com/samng/archive/tags/Dynamic/default.aspx"&gt;dynamic binding in C#&lt;/a&gt; and how that all plays in with the DLR, and about &lt;a href="http://blogs.msdn.com/samng/archive/tags/Named+arguments/default.aspx"&gt;named and optional arguments&lt;/a&gt; and how they change the way methods are bound. The only other major piece in C# 4.0 is this notion of COM interop. We chatted about how dynamic really is a gateway to interop with different object models and languages (ie interacting with dynamic languages, dynamic object models, javascript objects, HTML DOM etc), but in C# 4.0, we want to go a bit further and provide you a few more tools to help make your interop life much easier.&lt;/p&gt;  &lt;p&gt;These remaining features that we’ll chat about all have a strong tie to the COM world – that is, the features themselves require that the objects that you’re playing with are COM objects. How do we determine that? Well, you’ll soon find out!&lt;/p&gt;  &lt;h5&gt;Keep on rockin’ in a… COM… world!&lt;/h5&gt;  &lt;p&gt;Alright, I admit it – I’m a &lt;a href="http://en.wikipedia.org/wiki/Neil_young"&gt;Neil Young&lt;/a&gt; fan. The man wrote some great tunes! Anyway, the point is that Rock’n Roll ain’t goin’ nowhere. And either is COM. No matter how hard we try to get rid of it, it just won’t die! So we decided this time around that instead of trying to beat ‘em, we might as well join ‘em. &lt;/p&gt;  &lt;p&gt;We’ve therefore created several features that are geared towards making your COM programming experience much easier. First let me list them:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Passing non-ref arguments to by-ref parameters (aka COM omit ref in our world) &lt;/li&gt;    &lt;li&gt;Indexed properties &lt;/li&gt;    &lt;li&gt;No PIA deployment &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The first two of these are comparatively smaller features from a complexity standpoint, so we’ll tackle those one at a time. We’ll discuss the No PIA feature in length in the several posts following.&lt;/p&gt;  &lt;h5&gt;Passing non-ref arguments to by-ref parameters&lt;/h5&gt;  &lt;p&gt;The first feature is really an acknowledgement that the APIs generated for COM interop are quite poor. For those of you who have worked in any amount of detail with the Office PIAs, you’ll quickly realize that for some reason, just about everything is passed around by ref.&lt;/p&gt;  &lt;p&gt;This can get quite tiresome! Lets look at a quick Office example.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main()
{
    Word.&lt;span style="color: #2b91af"&gt;Application &lt;/span&gt;app = &lt;span style="color: blue"&gt;new &lt;/span&gt;Word.&lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;();
    &lt;span style="color: blue"&gt;object &lt;/span&gt;m = &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing;
    app.Documents.Add(&lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m);
}&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;This is such typical code! I have to struggle with the type system to make it happy, just to add a simple Word document!&lt;/p&gt;

&lt;p&gt;C# 4.0 makes this easier. The compiler will now determine that you’re working with a COM object by looking at the attributes of the type of that object, and checking to see if it has the [ComImport] attribute. Once it determines that you indeed are working with a COM object, it then gives you the ability to pass arguments to the method, index or property (yes, properties can have arguments a la indexed properties! We’ll talk about that later!) without giving them by ref. &lt;/p&gt;

&lt;p&gt;This is really just compiler syntactic sugar – the compiler does the work to generate the temporaries for you, and slot them in place of the actual arguments. That means that in the following code, call (1) gets transformed into call (2).&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main()
{
    Word.&lt;span style="color: #2b91af"&gt;Application &lt;/span&gt;app = &lt;span style="color: blue"&gt;new &lt;/span&gt;Word.&lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;();
    &lt;span style="color: green"&gt;// (1) Your initial call.
    &lt;/span&gt;app.Documents.Add(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing);

    &lt;span style="color: green"&gt;// (2) Compiler generates locals and inserts them.
    &lt;/span&gt;&lt;span style="color: blue"&gt;object &lt;/span&gt;m = &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing;
    app.Documents.Add(&lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m);
}&lt;/pre&gt;

&lt;p&gt;The great thing about this too, is that with the introduction of named and optional arguments, and using the fact that the feature generates Type.Missing in place of default values for object on COM types, we can simply remove the arguments altogether! &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main()
{
    Word.&lt;span style="color: #2b91af"&gt;Application &lt;/span&gt;app = &lt;span style="color: blue"&gt;new &lt;/span&gt;Word.&lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;();
    &lt;span style="color: green"&gt;// (1) Your optional-parameter-omitted initial call.
    &lt;/span&gt;app.Documents.Add();

    &lt;span style="color: green"&gt;// (2) Compiler generates locals and inserts them.
    &lt;/span&gt;&lt;span style="color: blue"&gt;object &lt;/span&gt;m = &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;.Missing;
    app.Documents.Add(&lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m, &lt;span style="color: blue"&gt;ref &lt;/span&gt;m);
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Pretty cool stuff huh? Definitely makes programming against the Office APIs much nicer. The added bonus is that the IDE helps you out by letting you know that the parameters are optional, indicating that you can omit them, and indicating what the default value used in place will be.&lt;/p&gt;

&lt;h5&gt;So why now?&lt;/h5&gt;

&lt;p&gt;Let’s get into a bit of a philosophy discussion now, about why we’re doing all these different COM interop features now. In the past, we’ve been asked for these features – nay, we even pushed back against some of them. &lt;/p&gt;

&lt;p&gt;For example, indexed properties is something that the VB language has had support for for quite some time now, but C# had decided that they weren’t the right way to go. Our standpoint was (and still is!) that the programming paradigm ought to be that the property is accessed, and that it is the thing that should supply the indexing.&lt;/p&gt;

&lt;p&gt;So why are we adding all these features in now?&lt;/p&gt;

&lt;p&gt;Well, for starters, COM’s pretty entrenched in the application programming world today. Many developers are having to struggle with the COM APIs and Office programming models every day, and it just doesn’t look like that model is going to be replaced, or will go away any time soon.&lt;/p&gt;

&lt;p&gt;Next, C# 4.0 is really an interop release. Our focus this time around was to be able to interop with different programming languages and programming models. It seemed only fitting that one of the largest programming models still out there ought to be pretty high up on our list of priorities. &lt;/p&gt;

&lt;p&gt;Dynamic binding allows for ease of interop with other object models and dynamic languages. The ability to use named and optional arguments allows ease of interop with legacy libraries like COM which have a lot of optional parameters, and large parameter lists. The introduction of the DLR, whose sole purpose is to provide a common runtime for interop with dynamic languages. All of these point us towards interop, and combined with the knowledge that COM interop has been a big pain point for our users really tipped the scale to pushing more interop features out this time around.&lt;/p&gt;

&lt;p&gt;Agree? Disagree? As always, with philosophy things (and with everything else for that matter), I’d love to get your feedback. Until then, happy coding!&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblogs.msdn.com%2fsamng%2farchive%2f2009%2f06%2f16%2fcom-interop-in-c-4-0.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblogs.msdn.com%2fsamng%2farchive%2f2009%2f06%2f16%2fcom-interop-in-c-4-0.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9763363" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/samng/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category><category domain="http://blogs.msdn.com/samng/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/samng/archive/tags/Omit+Ref/default.aspx">Omit Ref</category><category domain="http://blogs.msdn.com/samng/archive/tags/COM/default.aspx">COM</category><category domain="http://blogs.msdn.com/samng/archive/tags/Interop/default.aspx">Interop</category></item></channel></rss>