3

I have a ComVisible COM class written in C#. I want to call it from another C# bit of code using COM and pass the default value for the parameter. I can call plenty of other methods without default arguments.

This is the best I can come up with. The first two lines work for all my other methods.

Type mytype = Type.GetTypeFromProgID("MyType");
dynamic myinstance = Activator.CreateInstance(mytype);
object missingValue = System.Reflection.Missing.Value;
myinstance.generatecsvdocument("mystring", ref missingValue);

My method looks like this:

public void generatecsvdocument(string mystring, string rowseperator = "\n")

When I run it I get the error:

The best overloaded method match for 'generatecsvdocument(string, string)' has some invalid arguments

8
  • Is (string, string) overload really exist? Error message is quite self explanatory. Commented Sep 11, 2015 at 10:44
  • Well yes it does exist but I am passing System.Reflection.Missing.Value as the second argument which is not a string. Commented Sep 11, 2015 at 10:48
  • 1
    I don't think COM has default methods. C# does, but not all C# features are exposed in COM. Commented Sep 11, 2015 at 10:54
  • Yeah COM definitely has default methods. I may have to write the calling code in VB.net which at least supports optional arguments fully. Commented Sep 11, 2015 at 10:55
  • myinstance.generatecsvdocument("mystring") ? Commented Sep 11, 2015 at 11:00

1 Answer 1

3
  object missingValue = System.Reflection.Missing.Value;

That cannot work here. It is only valid for a COM method that takes a VARIANT as an argument. Looks like object or dynamic in C#. A very different kind of default argument mechanism than C# supports, it is the callee that determines the default value. In C# it is the caller that determines it, the C# compiler uses metadata to know that default.

Missing.Value turns in a variant of type vtError with the value DISP_E_PARAMNOTFOUND at runtime. Signalling the COM method to use the default value. Not actually that commonly used, usually only implemented in COM servers that support scripting languages. Office Automation is the most common example, probably what inspired you to try this.

But no, your argument is string, not a variant. There is no way to discover the default either when you use late binding, implicit is that you don't know anything about the default value stored in metadata. Otherwise the reason that the vtError mechanism exists, scripting languages have the same problem. The only real way to get ahead is to rewrite the method and test for a null argument, substituting "\n" if that's the case.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, it's not really possible to change the method as I can't change another bit of code that calls it. I am only calling it from C# to test my c# COM code really so I can change to use VB.net which I think will work better.
Hmya, common mistake. You are not really testing anything, the CLR is not that easily fooled. At can see at runtime that it is actually a .NET assembly and won't use COM interop. You might as well test it by adding the assembly reference, that default value will now work :)
Thanks I had tried that but was using the Interface as the type of the variable. If i switch to the actual class rather than the interface it can "see" the default values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.