Is there an 'Out' Keyword or Attribute for VB.NET?

Mike_R

Well-known member
Joined
Oct 20, 2003
Messages
316
Location
NYC
Does anyone know if there is a way to effect the C# out keyword in VB.NET? There is an OutAttribute, but this apparently is only for use when working through the COM Interop.

This does seem to be a weakness in VB.NET that bugs me from time to time -- for example, the compiler will warn about an unused variable that has actually been passed into a ByRef parameter, which is the best that VB.NET can do, as far as I can tell...

Does anyone know of a way to effect the out keyword in VB?

Thanks in advance for any thoughts on this...
Mike
 
The out keyword for C# is just to protect the programmer from himself (not saying that it is a bad thing; we build our programming styles around features like this to build sturdy code): to help him not use an uninitalized variable by explicitly declaring when the variable is intended to be initialized and using compile time errors and warnings to enforce this intent. It is nice to have, but does not effect what happens at runtime. An out parameter and a ref parameter compile to the exact same IL, also the same IL that a ByRef argument compiles to.

It breaks down to the fact that this is simply a programming practice that the VB compiler wont enforce for you. Even if you found the appropriate attribute, this is a feature that depends on the C# compiler, and it wont do you any good in VB. If worse comes to worse, you can initialize the variable to a default value to avoid the warning.

Just out of curiousity, what sort of code resulted in a compile error about an uninitialized variable? (I couldnt reproduce it.)
 
Hey, Thanks Marble Eater,

I just think that its a nice "handshake" making everything explicit what this variable is to do. ByRef is a tad sloppier, because it can work as an in/out parameter not just out. VB can force an out parameter by using a Function or Property Get procedure, so its not impossible to force an out interpretation, but, well, sometimes you want a "regular" parameter to be tagged as out.

As you suggested, I could initialize the variable, sure, to suppress the warning, or I could even just turn that warning off, but the real idea is to enforce the contract. As for the compiler error, its actually just a soft compiler "warning" so its no big deal... but this would not be occurring in C# if using the out keyword.

Even trying again now, I was almost unable to reproduce it, as it seems fine for value types. For example, the following shows no compiler warnings:
Code:
Sub MySub 
    Dim i As Integer
    ReturnInteger(i)    
End Sub
Sub ReturnInteger(ByRef out_Integer As Integer)
     out_Integer = 10
End Sub
Even with the code commented out, the compiler sees that the i variable is at least passed in somewhere to a ByRef parameter and looks no further. There is no warning on this code.

However, with a reference type, you can get a warning:
Code:
Sub MySub()
    Dim c As Class1
    ReturnClass1(c)
    MessageBox.Show(c.Name)
End Sub

Sub ReturnClass1(ByRef out_Class1 As Class1)
    out_Class1 = New Class1
End Sub

Public Class Class1
    Public Name As String = "Yoda"
End Class
The above runs 100% fine, of course, but the VB 2005 IDE will place a squigly line under the "c" within the line ReturnClass1(c), with the warning stating:
Variable c is passed by reference before it has been assigned a value. A null reference exception could result at runtime.

Not the biggest deal in the world, at all, but I was previously hoping that VB might recognize the OutAttribute, which upon reading is really only used for COM Interop marshalling. Oh well, maybe VB will add the out keyword some day, theres no reason for them not to...

Thanks for your thoughts here, ME,
:),
Mike
 
You will only get the warning with reference types as there is no way for a value type to ever be Nothing.

Now if you want a stranger idea try the following code
Code:
Sub MySub()
    Dim c As Class1 = Nothing
    ReturnClass1(c)
    MessageBox.Show(c.Name)
End Sub
this will suppress the warning about a null reference despite the fact it is still a possibility!
 
PlausiblyDamp said:
You will only get the warning with reference types as there is no way for a value type to ever be Nothing.
Ok, fair enough, I guess the most you could get there is an "unused variable" warning or the like, but, as I showed above, passing it in somewhere ByRef was enough to saticefy it...

PlausiblyDamp said:
this will suppress the warning about a null reference despite the fact it is still a possibility!
LOL. :p Pretty funny... Maybe someday well have full blown AI to trace through this sort of thing! :eek:

Thanks PD
 
Hmmm... More food for thought:
http://www.ayende.com/Blog/PermaLink,guid,b6e3e8ce-4a6e-4cf0-af70-d360be9e8c76.aspx

Why are out parameters a bad idea in .NET? Are they?

.Net doesnt verify that an out parameter is set inside a method that uses an out parameter before an exception is called. This mean that you may use an uninitialized parameter without the compiler catching on to this. Use ref parameters instead. Personally, I think that its a problem.
Im not sure that I agree with him here... (Or maybe I just dont understand him?) Generally, I think of an exception being thrown meaning that "all bets are off", and I would NOT expect a return value in this case. For example, if a Function or Property Get that is intended to return a value throws an exception, then no value is assigned. You cant even try to "trick it" into doing so by assigning the return value and then throwing the exception:
Code:
Function MyFunction() As Integer
    MyFunction = 5
    Throw New Exception
End Function
Any attemt to assign a variable to MyFunction will never execute, regardless of any Try..Catch..Finally protections. E.g.:
Code:
Dim i As Integer
Try
    i = MyFunction()
Catch ex As Exception
End Try
MessageBox.Show(i.ToString)
The above still returns 0.

So Im not sure what hes getting at... Anyway, I obviously have a strange bee in my bonnet today, Ill try to keep it in check. :p

Have a good one guys :),
Mike
 
Why are out parameters a bad idea in .NET? Are they?

.Net doesnt verify that an out parameter is set inside a method that uses an out parameter before an exception is called. This mean that you may use an uninitialized parameter without the compiler catching on to this. Use ref parameters instead. Personally, I think that its a problem.
He doesnt seem to understand the finer details of an exception. If you are to use a ref instead of an out, it will not provide any different behavior at runtime, just different compile-time error checking. It simply doesnt make sense. If a line of code throws an exception, the assumption should always be that the operation failed. Thats pretty much the only reason that exceptions are there: to give you a hint-hint-wink-wink-nudge that something went wrong during an operation and it did not succeed. It would be awefully silly of you to assume that the out parameters had been assigned to in an exception handler. It would be on par with something like this:
C#:
int i;
try{
    i = int.Parse("XXX");
    this.SomeProperty = i;
}
catch(FormatException ex){
    this.SomeProperty = i;
    // You dont assume that a value got returned, why
    // would you assume that an out param got assigned to?
}
 
Back
Top