1

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...

serhio
  • 28,010
  • 62
  • 221
  • 374
  • 1
    What is your question exactly? – Dirk Vollmar Jan 18 '10 at 12:47
  • @divo: How to eliminate the warning (without `#pragma` or other similar tricks)? – serhio Jan 18 '10 at 12:48
  • So is there a problem when you initialize the local variable with `Nothing`? – Dirk Vollmar Jan 18 '10 at 12:50
  • no, but VB.NET looks like limited from this POV – serhio Jan 18 '10 at 12:57
  • Then you might find these comments interesting: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=90489 and http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=90678. Adding `= Nothing` to the variable declaration seems not too much work as compared to an overly complicated static analyzer in the compiler (that might increase compilation time for each build process). After all, this is a warning and not a compiler error. – Dirk Vollmar Jan 18 '10 at 13:23
  • 2
    @divo: Yes, but when I worked in C# projects I always tried to code with 0 warnings and 0 errors. – serhio Jan 18 '10 at 13:31
  • 3
    @serhio - as you and divo have both aluded, there is a way to code here with 0 warnings and 0 errors - perform the "Nothing" assignment. Different languages have different voodoo incantations to appease the compilers. – Damien_The_Unbeliever Jan 18 '10 at 13:37

2 Answers2

3

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
  • 234,701
  • 27
  • 340
  • 448
  • as I mentioned, the (real) MyHour class could be really a structure... this is an interesting idea. – serhio Jan 18 '10 at 13:45
  • I can't declare MyHour as structure... there are used as optional parameters. Optional parameters can't be structures. – serhio Jan 18 '10 at 14:00
  • 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 Jan 18 '10 at 14:06
  • 2
    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 or overloads - it's friendlier to non-VB languages. – Damien_The_Unbeliever Jan 18 '10 at 15:29
  • 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 Jan 21 '10 at 06:47
0

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.

Community
  • 1
  • 1
peSHIr
  • 6,279
  • 1
  • 34
  • 46
  • 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 Jan 18 '10 at 13:36
  • 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. – invert Jan 18 '10 at 13:51
  • @Monkey: you are wrong. ByRef can set the external reference to nothing inside the calling method, ByVal can't. – serhio Jan 18 '10 at 14:10
  • 1
    @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 Jan 18 '10 at 21:57
  • @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 Jan 19 '10 at 14:45
  • @peSHIr: already discussed. See the Damien_The_Unbeliever comments. – serhio Jan 19 '10 at 14:56