Many of the parameters for interacting with the Office Object model in VSTO require object parameters that are passed by reference, even when the notional type of the parameter is an int or string.
The mechanism I've been using (cribbed from help and MSDN resources) essentially creates a generic object that contains the appropriate data and then passes that to the method, for example:
object nextBookmarkName = "NextContent"; object nextBookmark = this.Bookmarks.get_Item( ref nextBookmarkName ).Range;
Microsoft.Office.Interop.Word.Range newRng = this.Range( ref nextBookmark, ref nextBookmark );
This seems like a lot of extra code, but I can't see a better way to do it. I'm sure I'm missing something; what is it? Or is this really the best practice?
I think it was just poor design of the original Word object model. I know that passing strings by reference can be slightly faster in the COM world because it avoids the need to make a copy, so perhaps that was part of the justification. But the downside is that the callee can modify the value, and in most cases with Word they are input parameters.
I think your technique is the best practice. For the millions of optional parameters that many of the Word object model methods require, you can create a single static field "missing" something like:
object missing = Type.Missing;
// Example object fileName = ... document.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);