interoperation using COM from .NET with OptionalParameter

T

Tony Johansson

Hi!

I have this simple main Console program. If I use row marked with 2 below it
work but if I use row marked 1 I get runtime exception saying COMException
was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead of a
real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

//Tony
 
A

Arne Vajhøj

I have this simple main Console program. If I use row marked with 2 below it
work but if I use row marked 1 I get runtime exception saying COMException
was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead of a
real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

It is not valid because Excel is not expecting a null parameter.

It is expecting either a valid parameter or the parameter not
to be specified.

Calling with a null parameter and not specifying the parameter
is not the same.

C# (especially before version 4.0) is not good at not
specifying parameters. Which is why you have to use
the ugly Type.Missing.

COM is different and a lot more complex than pure .NET !

Arne
 
H

Harlan Messinger

Tony said:
Hi!

I have this simple main Console program. If I use row marked with 2 below it
work but if I use row marked 1 I get runtime exception saying COMException
was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead of a
real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

Because the underlying COM method call you're trying to invoke is not

Worksheets.Add Before:=null, After:=null, Count:=null, Type:=null

or

Worksheets.Add null, null, null, null

but

Worksheets.Add

You aren't supplying null as the argument for these parameters, you are
leaving the parameters unspecified. Two different things.
 
T

Tony Johansson

Harlan Messinger said:
Tony said:
Hi!

I have this simple main Console program. If I use row marked with 2 below
it work but if I use row marked 1 I get runtime exception saying
COMException was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead
of a real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

Because the underlying COM method call you're trying to invoke is not

Worksheets.Add Before:=null, After:=null, Count:=null, Type:=null

or

Worksheets.Add null, null, null, null

but

Worksheets.Add

You aren't supplying null as the argument for these parameters, you are
leaving the parameters unspecified. Two different things.


What I mean is that if I call a method Foo that take a Car object as the
only parameter I can pass null instead of a Car object and it will work. So
I still can't understand why I can't make this call
newExcelApp.Worksheets.Add(null, null, null,null);

//Tony
 
F

Family Tree Mike

Harlan Messinger said:
Tony said:
Hi!

I have this simple main Console program. If I use row marked with 2 below
it work but if I use row marked 1 I get runtime exception saying
COMException was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead
of a real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

Because the underlying COM method call you're trying to invoke is not

Worksheets.Add Before:=null, After:=null, Count:=null, Type:=null

or

Worksheets.Add null, null, null, null

but

Worksheets.Add

You aren't supplying null as the argument for these parameters, you are
leaving the parameters unspecified. Two different things.


What I mean is that if I call a method Foo that take a Car object as the
only parameter I can pass null instead of a Car object and it will work. So
I still can't understand why I can't make this call
newExcelApp.Worksheets.Add(null, null, null,null);

//Tony

That is only because you have coded routines where the parameter was of
type Car, and coded for the condition where the client passed a null
value into the method.

The assumption I believe you have made is that Excel is written in
csharp, and therefore could check the value being null. That is not the
case.
 
A

Arne Vajhøj

Harlan Messinger said:
Tony said:
I have this simple main Console program. If I use row marked with 2 below
it work but if I use row marked 1 I get runtime exception saying
COMException was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead
of a real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}

Because the underlying COM method call you're trying to invoke is not

Worksheets.Add Before:=null, After:=null, Count:=null, Type:=null

or

Worksheets.Add null, null, null, null

but

Worksheets.Add

You aren't supplying null as the argument for these parameters, you are
leaving the parameters unspecified. Two different things.

What I mean is that if I call a method Foo that take a Car object as the
only parameter I can pass null instead of a Car object and it will work. So
I still can't understand why I can't make this call
newExcelApp.Worksheets.Add(null, null, null,null);

Because the Excel code does not test for null as your Foo method does.

If your Foo method tested for Car.Missing, then you would need to
call with such.

The Excel code test for Type.Missing. Well - actually it does not.
But the .NET-COM wrapper does something so that you need to call
with Type.Missing to make sure that the right parameter end
up in Excel.

Arne
 
H

Harlan Messinger

Tony said:
Harlan Messinger said:
Tony said:
Hi!

I have this simple main Console program. If I use row marked with 2 below
it work but if I use row marked 1 I get runtime exception saying
COMException was undandled. Exception HRESULT: OptionalParameter.
The reason for this it that I can't send null as parameter value to a COM
function.

I mean normally it would be perfectly legal to send null values instead
of a real object so why is it not valid in this case ?

class Program
{
private static Object OptionalParameter = Type.Missing;

static void Main(string[] args)
{
Application newExcelApp = new Application();
1 newExcelApp.Worksheets.Add(null, null, null,null);
2 newExcelApp.Worksheets.Add(OptionalParameter, OptionalParameter,
OptionalParameter, OptionalParameter);
}
}
Because the underlying COM method call you're trying to invoke is not

Worksheets.Add Before:=null, After:=null, Count:=null, Type:=null

or

Worksheets.Add null, null, null, null

but

Worksheets.Add

You aren't supplying null as the argument for these parameters, you are
leaving the parameters unspecified. Two different things.


What I mean is that if I call a method Foo that take a Car object as the
only parameter I can pass null instead of a Car object and it will work.

It will "work" if and only if that method has been programmed to deal
with a null argument, and to deal with it in the way that you expect.
So
I still can't understand why I can't make this call
newExcelApp.Worksheets.Add(null, null, null,null);

Well, the answer I gave you is still the answer, despite your mistaken
belief that the equivalence of a null argument and an unspecified
argument is a necessary or universal phenomenon.

Here's an example: suppose a class C has a method M that sets three
member variables at once. I'm using C# syntax for clarity, but I'm using
pseudocode to simulate a way of indicating that a string argument is
Type.Missing, and that it can be checked for with something like
Type.IsMissing():

public class C
{
private string _x, _y, _z;
public C() { ... }
public void M(object x, object y, object z)
{
if (!Type.IsMissing(x)) _x = x as string;
if (!Type.IsMissing(y)) _y = y as string;
if (!Type.IsMissing(z)) _z = z as string;
}
}
...
C c = new C();

You should be able to see that

c.M("one", "two", null);

is not the same as

c.M("one", "two", Type.Missing);
 
T

Tony Johansson

Here's an example: suppose a class C has a method M that sets three member
variables at once. I'm using C# syntax for clarity, but I'm using
pseudocode to simulate a way of indicating that a string argument is
Type.Missing, and that it can be checked for with something like
Type.IsMissing():

public class C
{
private string _x, _y, _z;
public C() { ... }
public void M(object x, object y, object z)
{
if (!Type.IsMissing(x)) _x = x as string;
if (!Type.IsMissing(y)) _y = y as string;
if (!Type.IsMissing(z)) _z = z as string;
}
}
...
C c = new C();

You should be able to see that

c.M("one", "two", null);

is not the same as

c.M("one", "two", Type.Missing);


GOOD explained Harlan

//Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top