Mike_R Posted March 15, 2006 Posted March 15, 2006 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 Quote Posting Guidelines Avatar by Lebb
Leaders snarfblam Posted March 16, 2006 Leaders Posted March 16, 2006 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 won't enforce for you. Even if you found the appropriate attribute, this is a feature that depends on the C# compiler, and it won't 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 couldn't reproduce it.) Quote [sIGPIC]e[/sIGPIC]
Mike_R Posted March 16, 2006 Author Posted March 16, 2006 Hey, Thanks Marble Eater, I just think that it's 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 it's 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, it's actually just a soft compiler "warning" so it's 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: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: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©, 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, there's no reason for them not to... Thanks for your thoughts here, ME, :), Mike Quote Posting Guidelines Avatar by Lebb
Administrators PlausiblyDamp Posted March 16, 2006 Administrators Posted March 16, 2006 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 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! Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Mike_R Posted March 16, 2006 Author Posted March 16, 2006 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... this will suppress the warning about a null reference despite the fact it is still a possibility! LOL. :p Pretty funny... Maybe someday we'll have full blown AI to trace through this sort of thing! :eek: Thanks PD Quote Posting Guidelines Avatar by Lebb
Mike_R Posted March 16, 2006 Author Posted March 16, 2006 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 doesn't 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 it's a problem. I'm not sure that I agree with him here... (Or maybe I just don't 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 can't even try to "trick it" into doing so by assigning the return value and then throwing the exception: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.: Dim i As Integer Try i = MyFunction() Catch ex As Exception End Try MessageBox.Show(i.ToString) The above still returns '0'. So I'm not sure what he's getting at... Anyway, I obviously have a strange bee in my bonnet today, I'll try to keep it in check. :p Have a good one guys :), Mike Quote Posting Guidelines Avatar by Lebb
Leaders snarfblam Posted March 16, 2006 Leaders Posted March 16, 2006 Why are out parameters a bad idea in .NET? Are they? .Net doesn't 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 it's a problem. [/Quote] He doesn't 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 doesn't make sense. If a line of code throws an exception, the assumption should always be that the operation failed. That's 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: int i; try{ i = int.Parse("XXX"); this.SomeProperty = i; } catch(FormatException ex){ this.SomeProperty = i; // You don't assume that a value got returned, why // would you assume that an out param got assigned to? } Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.