this vs Item

Nov 29, 2007 at 6:46 AM
Why is it that the .NET reference documentation says that indexers have ID strings of the form "Item left-bracket type right-bracket", and this is how they are displayed in the Sandcastle-built documentation, but in XML processed by Sandcastle help builder, the syntax for referring to indexers is (apparently) cref="this left-bracket type right-backet"?

(I'd specify the XML in the post, but after 10 minutes of messing around I still don't see any info on how to do that in these forums.)
Nov 29, 2007 at 3:18 PM
Edited Nov 29, 2007 at 3:19 PM
That's probably more of a CLR question. I don't think VB.NET supports declaring an indexer using the equivalent of the this[int] syntax so you use the Item property instead to declare it. All compilers expose the indexers using the Item property but languages like C# let you access it using "this". As such, you use that syntax in C# but it shows up as Item in the documentation. That may not be completely accurate. You can probably ask in one of the MSDN forums for a more technically detailed answer.

By the way, to insert literal text enclose it in quote marks within curly braces. See the Wiki Markup Guide to the right of the text box when composing a message. There's a more detailed Wiki Markup Guide somewhere else on the CodePlex site. You can probably look around on the main page to find it.

Nov 29, 2007 at 7:03 PM
I would prefer to use the Item[type] syntax, since that is what the reference documentation describes, but the help system seems to recognize only this[type]. This does not seem like a CLR question; it seems like either a question about the way csc works, a question about Sandcastle and Sandcastle Help Builder; or a question about XML documentation standards. It would be ugly, maybe even a bug, if the syntax recognized in XML comments depended on the syntax of the nearby language, but I guess that is possible.
Nov 29, 2007 at 7:28 PM
Edited Nov 29, 2007 at 7:32 PM
I think it is a CLR/compiler issue as it is language dependent. If you look at the XML comments file generated by the compiler, you'll see that it converts the <see cref="this[int]" /> into the Item(Int) syntax. It makes sense in a way because Item(Int) doesn't exist and you can't access it that way in C# code. As I noted, the Item property exists as a workaround for other languages that don't support indexers in the way that C# and other languages do. If you look at the code using Reflector, you'll see the indexers listed in the member tree using the Item() syntax but if you view the member code, it varies based on the language chosen (this[] for C#, Item() for VB.NET, etc). This is also true of the Syntax Section in the indexer topics in the help file. As long as you are aware that the two are equivalent, I don't think it's an issue.

Nov 30, 2007 at 9:15 PM
Edited Nov 30, 2007 at 9:16 PM
I would agree that calling it a CLR/compiler issue is better than the earlier idea that it is a CLR issue. But I do not think it is a CLR/compiler issue only, because that leaves users of the documentation build process without information they need in order to write documentation. What obvious way is envisioned whereby they can find this information?

The syntaxes aren't equivalent. The Item syntax cannot be used in C# XML documentation.

It's probably the case that for many C# programmers, it's not obvious that the XML syntax is language-dependent, nor is it obvious what the language dependencies are. I can imagine the same issue arising with other cases too, e.g., operator naming. It is not easy to state what syntax should be used to refer to overloaded operators from C# XML documtation, if one does not already know.

The C# reference documentation describes ID strings for indexers in terms of Item, and Sandcastle-produced documentation refers to Item. So I would consider it surprising behavior that one cannot use Item[type] in C# XML documentation. It is easy to underestimate the pain that can come from this. Discovery is difficult. This is exacerbated by the 3 minute build time for Sandcastle to build documentation for "hello world" - experiments are painful. It took me 15 minutes to figure out the right answer, and more time to ask about it in forums. I think many people will spend even more time than that. The C# reference documentation doesn't help, and finding the answer in a search engine is not easy because 'item' and 'this' are very common terms. I was unable to find the answer in the Sandcastle Help GUI help files. I found the answer only after trial and error, after first trying things like not capitalizing the I in "Item", trying Item[long] instead of Item[Int64], etc. At 5 minutes per documentation build this was not fun.
Nov 30, 2007 at 9:54 PM
In fact, I am going through the same thing with operators. Based on the experience that Item is referred to using C# syntax, it seemed natural to try <seealso cref="operator<<(type,Int32)"/>. That of course didn't work, because less than signs have to be escaped in XML. So I tried operator&lt;&lt;(type,Int32). That didn't work either. Then I tried LeftShift(type,Int32), because that is how the operators show up in the documentation output. No dice. Next up is op_LeftShift(type,Int32). Nope. This is very painful since each attempt requires a 5 minute documentation build (even a documentation build of a minimal hello-world program takes 3 minutes). I still don't know the answer.
Dec 1, 2007 at 2:22 AM
Regarding the build times, see the Experimental release. It contains cached build components that may help especially if you've got MSDN links enabled.

Also, the compiler will complain and issue a warning if a cref target isn't valid. You don't have to build the documentation to find that out.

Regarding left/right shift operators and also generic types, you can use &lt; and &gt; or { and } for < and >. For example, the following work for the left shift operator. Interestingly, op_LeftShift also worked (and, yes, I tested them). The space between "operator" and the operator didn't seem to make a difference either.

<see cref="operator &lt;&lt;(Test1, int)"/>
<see cref="operator {{(Test1, int)"/>
<see cref="op_LeftShift(Test1, int)"/>

Dec 2, 2007 at 5:18 AM
Edited Dec 2, 2007 at 5:18 AM

> Regarding the build times, see the Experimental release. It contains cached build components that may help especially if you've got MSDN links enabled.

Just out of curiosity, why does the documentation build process take hundreds of times as long as executing the language compiler (csc)? Isn't compiling the more computationally difficult task?

> Also, the compiler will complain and issue a warning if a cref target isn't valid. You don't have to build the documentation to find that out.

That is good to know. I do a case insensitive search for text in the compiler output that does not contain the string 'warning' because right now I get a zillion warnings about components not having documentation. I see that there is a "Show Missing Tags" category and that it contains components for turning warnings on for these kinds of things. Is there a way to turn these warnings off, so that I can see the warnings I'm really interested in? (And shouldn't a reference to a nonexistent item be an error, not just a warning?)

About the operator references - I got them working after reading your post. Hallelujah. It turns out the reason that the things I tried didn't work is because I was using Int64 for the type of the shift length. I had forgot that C# requires the use of Int32 lengths for its overloaded operators, e.g.,prohibits shift lengths of type Int64. Maybe some warnings for these references were hidden amongst the other warnings. I never saw them..
Dec 2, 2007 at 8:38 PM
Build time for the documentation depends on a number of things. The two longest steps are usually the BuildAssembler step and the actual compilation of the help file. SHFB outputs timing info after each step so you can see what takes the longest. Regarding build assembler, at least 30 seconds of its time is spent initializing. If you have MSDN links enabled, it can easily double the build time as it has to query the MSDN web service for the URLs to the online framework documentation. A slower PC, less RAM, or a slower internet connection can impact the overall runtime of BuildAssembler. For the most part, it probably takes longer to run than compilation as it's performing a lot of XSL transformations and other operations on XML data which can be slow.

Regarding the warnings, you can disable specific compiler warnings. Just look at the compiler output and note the warning number (i.e. 1591 for the "missing XML comments" warning). Open up the Properties for the project, go to the Build page, and enter a comma-separated list of the warning numbers you don't want to see in the Suppress Warnings textbox. I think the most obvious reason that "missing documentation" and "invalid target" are warnings and not errors is that they are non-critical and you don't have to "fix" them in order to get a correctly running application. I wouldn't want to stop and add comments just to get the app running.

Dec 6, 2007 at 4:43 AM
Thanks for the warning info. I'll look for a non-GUI way to turn off a specified warning.

Have you considered using an internal representation that is faster than XML for the operations you need? Three minutes to build "hello world" is horrendous. With the modest-sized library I'm developing, documentation build times are already up to 5 minutes, and could easily get to 10 or 30 minutes. The less time a documentation build takes, the easier it is to write good documentation.

Dec 6, 2007 at 3:07 PM
Edited Dec 6, 2007 at 6:50 PM
If using the command line compiler, use the "/nowarn:[number list]" option. The cached build components use binary serialization to store and load the index file and MSDN URL caches. The other stuff loaded by the resolve links component is too complex and actually ran slower when done that way so it's better left to the XML in that case. The base components are written by Microsoft so I can't do much in the way of altering what they are doing.

Regarding your three minute build time for a "hello world" app, I find that hard to believe unless you've got some low end hardware and/or little memory. Most small projects (100 or so topics or less) build in a minute or so and usually less with MSDN Links disabled or when using the cached components.

Dec 6, 2007 at 7:33 PM
Thanks, I'll try /nowarn.

My machine is a 1.9 GHz Athlon with 1 GB of memory. The disk is highly fragmented. The 3 minutes for "hello world" was with the previous version of SHFB, so maybe things are faster now. But I doubt it - the library I build documentation for has 100-200 topics; it takes around 1 second to build with csc and about 5 minutes to build documentation with SHFB I don't think I changed the SHFB default build configuration parameters. It doesn't seem as though there is anything particularly unusual about my setup, and given the 3 minute build time for "hello world" with a previous SHFB version, I doubt the problem is with the library I'm writing. I would hope that the default SHFB configuration would be good enough to get reasonable build times.

Are you developing SHFB while not working for MIcrosoft?
Dec 6, 2007 at 9:44 PM
SHFB is a community tool, I don't work for Microsoft. I wanted features similar to NDoc so started playing around when Sandcastle was first released and it's grown from there. Complaints about its speed aside, Sandcastle is quite extensible and I've been able to add a lot of features that I couldn't get with NDoc.

Note that with you do have to edit the ComponentConfigurations to add the cached build components into the project. Presentation style can have an affect on build time. VS2005 and Hana tend to be slower than Prototype. The default is to have MSDN links enabled too and with a slow connection or if the MSDN web service is slow to respond, that can more than double build times. Once you add the cache components and do a build, subsequent builds should be on par with setting SdkLinkType to None.