Optional parameters question

D

David C

I have a Class function that I want to default 2 parameters as null if not
passed. I have the code below at the top of the shared function. I am
getting an underlined error that says "Constant expression is required" on
the last parameter. Can anyone tell me how to resolve this? Thanks.

David

Public Shared Function CreateHistoryDates(ByVal intPeopleLinkID As
Int32, _
ByVal intHistoryTypeID As
Int16, _
ByVal intHistoryReasonID As
Int32, _
ByVal dtHistoryDate As Date, _
Optional ByVal dtHistoryDateTo
As Date = DBNull.Value, _
Optional ByVal strHistoryText
As String = DBNull.Value) As Boolean
 
S

Scott M.

David C said:
I have a Class function that I want to default 2 parameters as null if not
passed. I have the code below at the top of the shared function. I am
getting an underlined error that says "Constant expression is required" on
the last parameter. Can anyone tell me how to resolve this? Thanks.

David

Public Shared Function CreateHistoryDates(ByVal intPeopleLinkID As
Int32, _
ByVal intHistoryTypeID As
Int16, _
ByVal intHistoryReasonID As
Int32, _
ByVal dtHistoryDate As Date,
_
Optional ByVal
dtHistoryDateTo As Date = DBNull.Value, _
Optional ByVal strHistoryText
As String = DBNull.Value) As Boolean

There are several problems with your code, but the immediate problem, which
is causing the "Constant expression is required" error message is being
caused because, while the property "Value" of the DBNull type may always
return back the same result, it is defined as a readonly field, which is not
the same as a "constant" expression. You must either set the parameter to
an actual "constant" type that has been defined somewhere else or supply a
hard-coded "constant" value.

So, that means that your Date parameter must be passes an actual Date
constant or you must supply a hard-coded Date value and your String
parameter must be set to a String constant or be hard coded to a String
object reference. As you are passing your parameters ByVal (the default and
most likely the desired choice), Date parameters are Value Types and will
hold a value and String parameters are Reference Types, they hold a
reference to a String object.

Other issues:

Optional parameters, by definition, must be supplied a default value.
DBNull.Value is not sufficient as it means "no value", which conflicts with
the optional parameter rule.

Here are some other reasons why this won't work:

1. A Date is Value Type. Value Types generally cannot be Null.
2.With a String, setting it to DBNull.Value doesn't affect the String data,
it affcts the *reference* that the String *variable* refers to because
Strings are Reference Types. As such setting the String parameter to
DBNull.Value doesn't make any sense as it means that if no String is passed
then your String parameter should hold a reference to Nothing, but Optional
parameters cannot

So, one solution would be to supply actual hard-coded values for your Date
and String (Some date that indicates not a valid date, like #01/01/1900# and
perhaps an empty string ("").

But, realy the better solution would be to not use Optional Parameters at
all and instead use Overloading, which would allow you to write a version of
your method that doesn't take those last two parameters at all and simply
sets the values of the Date and String using a Nullable(Of Date) set to
DBNull.Value and a String set to String.Empty.

If you include both of the following, you'll solve your problem, as in:

Public Class Foo

Private theDate As Nullable (Of DateTime)
Private theString As String

Public Shared Function CreateHistoryDates( _
ByVal intPeopleLinkID As Int32, _
ByVal intHistoryTypeID As Int16, _
ByVal intHistoryReasonID As Int32, _
ByVal dtHistoryDate As Date, _
ByVal dtHistoryDateTo As Date, _
ByVal strHistoryText As String) As Boolean

End Function

Public Shared Function CreateHistoryDates( _
ByVal intPeopleLinkID As Int32, _
ByVal intHistoryTypeID As Int16, _
ByVal intHistoryReasonID As Int32, _
ByVal dtHistoryDate As Date) As Boolean

'Since the last 2 parameters are not being
'passed to this version of the method, we
'can safely manually set them to the Null/Empty
'values we desire.
theDate = DBNull.Value
theString = String.Empty

End Function

End Class

Optional Parameters are "legal" in VB .NET, but really only exist to support
legacy code brought in from VB 6. Using Overloaded class memebers is the
more OO way of doing this, and as you can see, makes the code much easier to
write and maintain.

-Scott
 
D

David C

Scott M. said:
There are several problems with your code, but the immediate problem,
which is causing the "Constant expression is required" error message is
being caused because, while the property "Value" of the DBNull type may
always return back the same result, it is defined as a readonly field,
which is not the same as a "constant" expression. You must either set the
parameter to an actual "constant" type that has been defined somewhere
else or supply a hard-coded "constant" value.

So, that means that your Date parameter must be passes an actual Date
constant or you must supply a hard-coded Date value and your String
parameter must be set to a String constant or be hard coded to a String
object reference. As you are passing your parameters ByVal (the default
and most likely the desired choice), Date parameters are Value Types and
will hold a value and String parameters are Reference Types, they hold a
reference to a String object.

Other issues:

Optional parameters, by definition, must be supplied a default value.
DBNull.Value is not sufficient as it means "no value", which conflicts
with the optional parameter rule.

Here are some other reasons why this won't work:

1. A Date is Value Type. Value Types generally cannot be Null.
2.With a String, setting it to DBNull.Value doesn't affect the String
data, it affcts the *reference* that the String *variable* refers to
because Strings are Reference Types. As such setting the String parameter
to DBNull.Value doesn't make any sense as it means that if no String is
passed then your String parameter should hold a reference to Nothing, but
Optional parameters cannot

So, one solution would be to supply actual hard-coded values for your Date
and String (Some date that indicates not a valid date, like #01/01/1900#
and perhaps an empty string ("").

But, realy the better solution would be to not use Optional Parameters at
all and instead use Overloading, which would allow you to write a version
of your method that doesn't take those last two parameters at all and
simply sets the values of the Date and String using a Nullable(Of Date)
set to DBNull.Value and a String set to String.Empty.

If you include both of the following, you'll solve your problem, as in:

Public Class Foo

Private theDate As Nullable (Of DateTime)
Private theString As String

Public Shared Function CreateHistoryDates( _
ByVal intPeopleLinkID As Int32, _
ByVal intHistoryTypeID As Int16, _
ByVal intHistoryReasonID As Int32, _
ByVal dtHistoryDate As Date, _
ByVal dtHistoryDateTo As Date, _
ByVal strHistoryText As String) As Boolean

End Function

Public Shared Function CreateHistoryDates( _
ByVal intPeopleLinkID As Int32, _
ByVal intHistoryTypeID As Int16, _
ByVal intHistoryReasonID As Int32, _
ByVal dtHistoryDate As Date) As Boolean

'Since the last 2 parameters are not being
'passed to this version of the method, we
'can safely manually set them to the Null/Empty
'values we desire.
theDate = DBNull.Value
theString = String.Empty

End Function

End Class

Optional Parameters are "legal" in VB .NET, but really only exist to
support legacy code brought in from VB 6. Using Overloaded class memebers
is the more OO way of doing this, and as you can see, makes the code much
easier to write and maintain.

-Scott
I was not aware you could have 2 methods (CreateHistoryDates) of the same
name in the same Class.

David
 
S

Scott M.

I was not aware you could have 2 methods (CreateHistoryDates) of the same
name in the same Class.

David

Absolutely. This is called "Overloading" and is allowed as long as the two
(or more) versions of the method have different *signatures* (their
parameter types, amount of paramters, and order of the parameters). This is
a basic feature of most OO languages.

When you are working in Visual Studio and the IntelliSense advises you that
there is more than one way to complete a parameter list for a given
constructor or method call by saying (1 of X) in the tooltip, it is Visual
Studio's way of telling you that the method has been overloaded by the class
author and that there are several different versions of the method available
for you to call.

This eliminates the need to write one, mega-method, that has bunches of
optional parameters.

-Scott
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top