views:

73

answers:

2

When in C# we have the out and ref parameter options, in VB there is a only one: ByRef.

Now, little 'problem' when trying to 'eliminate' the compiler warning saying that test was not initialized before passing as argument:

Dim test As MyParsableClass ' = Nothing  need imperatively?? '
' some code ... '
MyParsableClass.TryParse("value", test) ' warning on "test" here

the class brief declaration:

Class MyParsableClass

  Public Shared Function TryParse(ByVal value As String, _
    ByRef myParsableClass As MyParsableClass) As Boolean
    myParsableClass = Nothing
    If True Then
      ' parse code OK'
      myParsableClass = New MyParsableClass()
      Return True
    Else
      ' parse code NOK '
      ' myParsableClass remains Nothing '
      Return False
    End If

  End Function

End Class

maybe a solution was to declare

...Optional ByRef myParsableClass As MyParsableClass = Nothing)

but I can't set this parameter as optional one. What will happen if I'll miss it?

PS. (edit)

In the real project, my "parsable" class is MyHour with Hour and Minute properties. I wrote already the Parse(value as String) with a FormatException, but I think the code could be more clear, compact and quick when I will not use try catch blocks...

A: 

Not exactly an answer to your question, but out and ref/ByRef are bad, so why use them in the first place? Many developers think that the TryParse paradigm in the .NET Framework 1.0 was a bad way to go.

Why not go for a MyParsableClass that has a Public Shared Function Parse(ByVal value As String) As MyParsableClass method that raises an appropriate exception when needed?

Or even a Public Shared Function Parse(ByVal value As String) As MyParsableClassParsed where, MyParsableClassParsed is a helper inner class that contains two readonly properties: Success As Boolean and Result As MyParsableClass? You could then always get a result from calling Parse, but you'd get Success==True and Result==[whatever], or simply Success==False and Result==Nothing.

Also, your MyParsableClassParsed helper class could also use an enumerator instead of a boolean and/or a list of error messages to tell the caller how/why the parse operation failed. Or the throw exception might have such an enumerated value and/or error message(s).

Much easier to use and more flexible. And all without ByRef to give you headaches/warnings.

peSHIr
in reality, my parsable class is `MyHour` with `Hour` and `Minute` properties. This will not be very clear if I'll add also `Success` and `Result` properties... I wrote already the `Parse(value as String)` with a FormatException, but the code is more clear, compact and quick when I don't use try catch blocks...
serhio
Just pointing that all objects not derived from System.ValueType are handled ByRef implicitly, ie your class is ByRef whether you specify it in the method parameter list, or not.
Wez
@Monkey: you are wrong. ByRef can set the external reference to nothing inside the calling method, ByVal can't.
serhio
@Monkey: All parameters are passed ByVal by default, even reference types. The only time parameters are passed by reference is when the ByRef keyword is used.
Chris Dunaway
@serhio: Ah, for such a "simple" case (I assumed more complex parsing), you probably have `MyHour` defined as a `Struct` (not a `Class` and you could define a TypeConverter for it. See http://stackoverflow.com/questions/1866552/1866620#1866620
peSHIr
@peSHIr: already discussed. See the Damien_The_Unbeliever comments.
serhio
+3  A: 

I do not believe it's possible to prevent this warning, without an explicit assignment.

Different languages have different features/facilities - if they didn't, there'd only be one programming language :-) In this case, yes, VB doesn't pretend that there are two types of ref parameters, as C# does - so far as the CLR is concerned, "out" doesn't exist.

And I'm not sure what peSHIr is talking about - TryParse was added to later releases of the BCL for precisely the situation where a parse is as likely to fail as to succeed - so you can take a faulting path without requiring an exception to be thrown.

Edit

To add - the reason you don't get a warning for many of the built in types for which a TryParse exists (e.g. Int32) is because they're Structs/Value types, and hence always have a value. If your class is simple enough, would it be logical for it to be a Structure instead?

Damien_The_Unbeliever
as I mentioned, the (real) MyHour class could be really a structure... this is an interesting idea.
serhio
I can't declare MyHour as structure... there are used as optional parameters. Optional parameters can't be structures.
serhio
Also structures can't have parameter-less constructors nor protected members, their members can't be initialized when declaring, I can't implement IComparable with Equals(object) etc etc..
serhio
Ah, this is why I asked whether it would be logical - obviously, I didn't know which additional constraints you had on your implementation - although (in the specific instance of) Optional parameters may be better dealt with as NUllable<T> or overloads - it's friendlier to non-VB languages.
Damien_The_Unbeliever
It was not a bad idea that something like `TryParse` was added (as an option to just always getting an `Exception` on `Parse`), but the way it was implemented (=using an `out` parameter) that many people think was a bad call. Microsoft is in this camp, which is why you get the warning serhio was asking about.
peSHIr