Possible unpleasant side effects of .NET cheating have optional ref parameters for COM

FINAL IMAGE

I tested the “function” more thoroughly and wrote a full article about this: Optional passed using C # reference parameters for VBA COM APIs

Any feedback is appreciated.


For some reason, in C # a method cannot have optional parameters passed by reference (marked ref or out ).

But in other infrastructures, such as VBA , VB6 or COM , this is possible.

When connecting C # to VBA using COM , I found a way to overcome the C # restriction by marking the ref parameters as [Optional] , which is the AFAIK that the C # compiler generates at the end of its plumbing.

 void SomeDotNetCSMethod([Optional] ref someParameter) 

This is like a charm: when calling from VBA to C #, I can omit the ref parameters, and of course I can read and modify them from .Net / C #.

But since I did not find a single entry about this, I would like to make sure that with this “trick” there are no side effects.

Do you know anyone? You can imagine?


EDIT

With the [DefaultParameterValue] attribute, I might have found a way to get VBA default values ​​for a parameter, but only for some types.

I will do more tests to confirm that this works as expected ...

+7
c # vba excel-vba com
source share
1 answer

No, this is not a general way of specifying an optional argument. You take advantage of the rather bizarre feature added in C # v4, it made the programming of Office interop more complicated. Usually you can expect it to have the intended effect, the closer the interaction layer will look like VBA or IDispatch (also known as COM Automation). This is not a general COM mechanism, the more universal way is the client compiler to observe the [defaultvalue] attribute in the type library and apply the value in the method call. Very similar to C #.

The type of the argument is of great importance, you forgot to specify it in your fragment. But with the expectation that this is an object. Which corresponds to VARIANT on a COM server, a fairly common type in Visual Basic. Also explains ref, the default argument passed in older versions of VB was ByRef.

Before C # v4, it was very tedious to write C # code to call such a server, in particular, the Interop code for Office was overflowed with a very large number of ref Type.Missing . Otherwise, there is a need to support scripting languages, such as environments where it is not possible to determine the default value of an optional argument from a type library. Thus, an agreement was made to transmit the caller’s signal not to specify an argument for the called subscriber; they chose the vtError type vtError with the value set to DISP_E_PARAMNOTFOUND . Compatible with IDispatch :: Invoke ().

Please note that this is very, very different from how additional parameters are handled in C # and in any other language. Always the caller, which resolves the default value for the optional argument, the caller does not fully realize that the code omitted the argument. In the case of C #, this default value is encoded as the .param value in the metadata. The compiler uses the default, when necessary, to compile a method call.

If the argument type is not an object, you call another quirk, now the caller sets the default value. It will be null for the object or interface. And, of course, it depends on how the code you invoke interprets the value of the variant as "optional." Note that vtNull or vtEmpty can have the same semantic meaning.

+1
source share

All Articles