I've been happily writing code like this:
For idtArticles = 0 To dtArticles.Rows.Count - 1
and this:
If request.QueryString.HasKeys() Then
For Each parameter In request.QueryString.AllKeys
requestVars.Add(parameter, request.QueryString(parameter))
Next
Else...
And suddenly it won't compile and giving errors
Error 34 'idtArticles' is not declared. It may be inaccessible due to
its protection level. ..userAccountModel.vb
Which assuming I can't go back to my lazy ways is fine to edit as
For idtArticles as Integer
But I don't know for exampple what the Request collection would be declared as..
Error 39 'Parameter' is a type and cannot be used as an
expression. ..userAccountModel.vb
How can I make it go back to not caring? Also if not, what shall I DIM that Parameter as?
I've checked and Option Strict is OFF. In Tools.. Default Project Settings.
Thanks!
From Microsoft Doc on Option Infer Statement:
When you set Option Infer to On, you can declare local variables
without explicitly stating a data type. The compiler infers the data
type of a variable from the type of its initialization expression.
I would try this at the top of your code file:
Option Infer On
Or, alternatively you can change this on My Project -> Compile - Option Infer, right under Option strict!
Related
When Option Strict is turned Off, which is the default for my application, VB will automatically convert the value when property is String. It appears to call the toString() of the incoming value's Object. I believe casting will work for any property that can be safely casted (eg integer to double). I want the properties to behave in a strict manner, in that the Type passed MUST match the type on the declared property.
Is there a way to make Objects Properties Strict at the Object level without having to resort to the Option Strict On configuration on?
For example:
Option Strict Off
Class TestObj
Private _foo As String
Public Property Foo as String
Get
Return _foo
End Get
Set(v As String)
console.write(String.format("v = <{0}> {1}", v.GetType().FullName, v))
_foo = v
End Set
End Property
End Class
Dim o as new TestObj()
o.Foo = "some_str"
o.Foo = 1234
o.Foo = DateTime.now()
In the above case, all values are converted to Strings at arrival to the setter:
v = <System.String> some_str
v = <System.String> 1234
v = <System.String> 7/7/2022 8:22:49 PM
I am aware of DynamicObject and ability to tightly control setters like Python's __setattr__ but this breaks autocomplete functionality in editors as it would preclude defining properties on the class to get the functionality.
I strongly agree with the commenters that Option Explicit On and Option Strict On are simply a must - as the default settings of Visual Studio for new VB projects as well as for each project within the solution(s) you took over.
I my opinion one has to invest first some effort into clean-up work when taking over legacy solutions including
Add an ".editorconfig" if there isn't any
Convert the projects to SDK projects where possible
Go through the code and
format the code to your liking using the current naming convention where possible
correct/complement/remove/translate-to-English the documentation comments
add some //TODO: - comments where refactoring is needed wherever you notice a code repetition, repeated property access, huge methods that needs to be split into smaller parts, if-not-condition-then-else that needs to be reverted etc. but don't code it yet - these refactorings could introduce some bugs, we need to finish the next step first.
put every top-level type in its own file (except overloaded generic types of the same name) and make sure the type name matches the file name
Go through the unit tests and fix them, remove unnecessary ones and complement the missing ones.
Change all projects to Option Explicit On, Option Strict On and Option Compare Binary (use explicit StringComparer.OrdinalIgnoreCase / StringComparer.InvariantCultureIgnoreCase where needed). (Option Infer On or Off, what you prefer). If you hate to have 1000s of errors, add an Option Strict Off on top of each VB file which you later removed again file by file, otherwise do a bulk mutation.
Fix all compile errors (per file or bulk mutation)
Run unit tests, fix code of failing tests (repeat this after each of the following steps)
Update the .NET framework version if possible (e.g. to current or .NET 4.8)
Update the NuGet packages
Do all the previously tagged refactorings
Enable the analyzer warnings
Fix all the warnings and infos or suppress them, individually or in the project file by adding the according entry to the <NoWarn> element.
Start implementing the changes why you originally cloned the repository...
Of course that comes with a price but not doing it also has its price - I'm certain you are going to find dozens of little mistakes in the original code during the process of going Strict. And the time one spends formatting the code files is not just wasted time neither as in the process one also learns to understand the code...
Consider the following line of code which used to compile without warnings.
Public SetUpDone = False
After upgrading a project to Visual Studio 2017 from Visual Studio 2005 over a hundred of these BC42020 warnings exist. The MSDN description of the warning simply states that the variable defaults to type object. I don't have a good idea of the seriousness of this type of warning. The debugger indicates that the code executes as I expect. Is it merely a performance type of issue?
Secondly, I thought that Visual Basic supported some form of Type Inference so I'm not clear about why it wouldn't be able to deduce that the type should be Bool.
Another example is the following where the function returns a String
Dim dayTxt = " " & GetTextFromIni("General", "Var50")
I would have thought that type inference would work here and deduce that dayTxt is a String.
This:
Public SetUpDone = False
Is equivalent to this:
Public SetUpDone As Object = False
As suggested, type inference is only for local variables, not fields. With Option Infer On, this inside a method:
Dim SetUpDone = False
would indeed be equivalent to this:
Dim SetUpDone As Boolean = False
There are a couple of issues with the code as you have it. Firstly, it means that every use of that False value requires unboxing which makes your code slower. That's the case for any value types, i.e. structures. Value types are normally stored on the stack but, when boxed, are stored on the heap.
Secondly, it means that any member access will require late binding. That's not an issue for Boolean values because they have no members of interest anyway but if it was, say, a DateTime then the IDE would never provide Intellisense for that type because al it would see would be type Object and the existence of the specified member would have to be confirmed at run time, making the code less efficient again.
Thirdly, it means that the compiler can never confirm that you're passing the correct type as a method argument. For instance, if you have a method with a Boolean parameter, the compiler won't know that you're passing a Boolean if you pass that field because it's type Object. That also means that if you pass some other Object variable that doesn't contain a Boolean, the compiler can't warn you.
As suggested, you should turn Option Strict On in the project properties. That will flag every instance of you're not specifying the appropriate type for something. Fixing those errors will, at the very least, make your code a bit more efficient. It may even draw your attention to situations where exceptions will or could be thrown at run time. Having Option Strict On enforces strict typing so it makes you think more about the types you're using. Even if you're conscientious about that with Option Strict Off, you can still make mistakes that Option Strict On will prevent.
I'm turning On Option Strict on all project in my newly inherited VB.NET application. I'm mostly adding alot of CStr, CBool, CType statements to get rid of all the compile errors.
Dim x As String = someObject
dim val As SomeEnumType = 1
becomes
Dim x As String = CStr(someObject) ' Not .ToString() because someObject could be Nothing
Dim val As SomeEnumType = CType(1, SomeEnumType)
etc.
I'm doing everything pretty much by hand one error at a time and have a test application to test the Nothing, ... bordercases.
But is it possible I'm missing something that is going to generate exceptions at runtime?
And what kind of code is being generated due to Option Strict? Is it just some conversions that are going to be added or does OptionStrict do other things aswell?
Option Strict On does not generate any extra code, it merely tells the compiler to generate errors when your vb.net statements are relying on implicit type conversions. Like assigning an object to a string. What you've written in your snippet is exactly what the compiler does with Option Strict Off so no extra code is generated by your type conversion operators.
But of course, there's always a non-zero chance that you use the wrong conversion and break the existing code. You'll have to do what's always required when you make changes to code, you'll have to re-test it.
I'm writing some code in Visual Basic 6 and I have noticed that I don't even need to declare variables for things to work.
The following (explicit declaration):
Dim foo As String
foo = "Bar"
Seems to work just as well as this (implicit declaration):
Dim foo
foo = "Bar"
Or this (no declaration):
foo = "Bar"
I know in C# I need to declare a variable before I use it, and that implicit and explicit declarations are both acceptable. I also know that in Python, you don't declare your variables at all before you use them.
In regards to Visual Basic 6 (and by extension VBA) which is proper?
Thanks
It's a good HABIT.
There is a VB option called Option Explicit. With that set to ON, then VB forces you to declare a variable before you use it: no more
foo = "Bar"
That helps with mistyping the variable name later in your code... without that, you can typso the variable name, your program compiles but won't work, and it's HARD to dig that out.
In Tools/Options, Editor tab, check the Require Variable Declaration checkbox. This will automatically add Option Explicit to every new code module.
I would say this is more than a best practice; I think of it as a requirement for programmer sanity. The setting is persistent; once set, it stays enabled. Microsoft made it an option because some older versions of VB didn't have the feature, which also explains why it was disabled by default.
Should I explicitly declare my variables in VB6?
Yes. Why?
Not just because it is a good habit or it is a must but because of only one main reason which I have mentioned in this post as well.
VB defaults the variable to being type Variant. A Variant type
variable can hold any kind of data from strings, to integers, to long
integers, to dates, to currency etc. By default “Variants” are the
“slowest” type of variables.
AND
As I mentioned earlier, If you do not specify the type of the
variable, VB defaults the variable to being type Variant. And you
wouldn’t want that as it would slow down your code as the VB Compiler
takes time to decide on what kind of variable you are using. Variants
should also be avoided as they are responsible for causing possible
“Type Mismatch Errors”.
Topic: To ‘Err’ is Human (See Point 3)
Link: http://siddharthrout.wordpress.com/2011/08/01/to-err-is-human/
The above link also covers other parts related to coding that one can/should take care of.
HTH
I highly reccomend that you always declare your variables. This can be forced by setting Option Explicit in each code module. You can let VB6 do that automatically for you by going to Tools->Options, in the Editor tab check Require variable declaration.
If you don't use Option Explicit, then a variable will be automatically created for you each time you reference a previously unknown variable name. This is a very dangerous behavior, because if you mistype a variable name, an empty variable will be created for you, causing unexpected behavior of your code.
You don't have to declare the type of your variables but I would also recommend that you do that. The default type of a variable is Variant, which has a small performance overhead and create some problems if you are creating COM objects for use by C++ or C# (if anybody does that anymore).
http://msdn.microsoft.com/en-us/library/87x5f80y%28v=vs.80%29.aspx
I know the error and why. I am just curious. For some projects this show up as warning while for others this doesn't show up at all.
How do I set up so that the warning show up?
Information of the warning: http://msdn.microsoft.com/en-us/library/87x5f80y(v=vs.80).aspx
Information of how to hide or treating it as error: Goto the Compile tab of the Project Designer.
Note: There is differencies in what type of object you create. In then example below, only test1 will give warning, not the test2 function.
Function test1() As String
End Function
Function test2() As Integer
End Function
You can also use compiler options to hide warnings or threat them as errors. This specific warning has the ID 42105:
Function or Operator without Return Value Warning
Generated when the function does not have a return value specified.
Default for new projects is on. ID: 42105 function
More information about how it works here: http://msdn.microsoft.com/en-us/library/3y20cc1z(v=vs.80).aspx
When Option Strict is set to Off, Option Strict related warnings cannot be treated independently of each other. When Option Strict is set to On, the associated warnings are treated as errors, no matter what their status is. When Option Strict is set to Custom by specifying /optionstrict:custom in the command line compiler, Option Strict warnings can be toggled on or off independently.