Prevent implicit import of modules [duplicate] - vb.net

I have a situation where I have several VB.NET Modules in the same Logical-Module of a large application.
I would like the update function of each module to be public, but I would like users to be forced to qualify the function call with the module name.
ModuleName.Update()
instead of
Update()
Is this possible?
Thanks.

No.
The VB.NET specifications automatically use Type Promotion to allow this behavior to occur. The only way to avoid this is to have a type at the namespace that has the same name (Update) which would prevent (defeat) the type promotion provided in VB.NET.

Yes, it is possible, if you are willing to wrap the module within a namespace of the same name as the module:
Namespace ModuleName
Module ModuleName
...
End Module
End Namespace

Using modules is usually a poor design, because its methods become visible directly in the name space.
Consider replacing them with Classes. Put Shared on all the members:
Class ClassName
Public Shared Property SomeData As Integer
Public Shared Sub Update()
End Sub
End Class
Update would be referenced as:
ClassName.Update()
Make it impossible to instantiate, by having a Private instance constructor (is NOT Shared):
Private Sub New()
End Sub
Any needed class instantiation can be done like this:
Shared Sub New()
... code that runs once - the first time any member of class is accessed ...
End Sub

Related

Using vb.net, how can I use a class, which does not have a namespace?

I have a file called class.vb.
In a separate project, I would like to utilize this class. However, class.vb doesn't use a namespace.
class.vb:
Imports System
Public Class MyClass
Public Sub DoSomething()
Console.WriteLine("Hello")
End Sub
End Class
Attempting to illustrate what I would like to do:
Imports MyAlias = C:\whatever\class.vb
Public Class MyOtherClass
Public Sub DoSomethingElse()
MyAlias.MyClass.DoSomething()
End Sub
End Class
If this is possible, what's wrong with doing this? Perhaps there are differences between how a normal namespace import works and the file import..
To utilize an already existing class you need to right click on the folder (or simply the project) you want to add your class in (from visual studio) and do Add Existing Item. Then browse your file explorer and select your class. Once done it should be included properly.
If the class uses other classes from your previous project make sure you include them aslo.
If there are still problems after that you could simply create an empty class and copy paste the content into it

Intellisense in private modules

Assume I have a module named Module1 with the following code:
Private Sub MyPrivateSub()
'do something
End Sub
Public Sub MyPublicSub()
'do something
End Sub
Public Sub test()
End Sub
If I place the cursor inside Test() and start typing "MyPrivateSub" or "MyPublicSub", I don't get any intellisense. I can type "Module1." (or "Me." if Module1 were a class module) to get an intellisense menu, but this only contains the public method MyPublicSub, as shown here:
Is there some way to get an intellisense menu for all members, public and private? I'm working on a project with modules that have many methods, and going up and down continually to copy/paste member names is time consuming.
Short answer
hit a combination of
CTRL+SPACE
and start typing the sub name like shown here
Long answer
Everything you do in programming matters. When you decide to make your sub/function/variable private you do that for a reason and you need to understand how this will affect the access level and "scope".
The scope of a member is dictated by its access level and in VBE anything that is private and qualified with it's parent member does not get intelli-sense. Simply, because you can't (are not supposed to be able to access it) from the outside.
Because your MyPrivateSub access level is Private you can't access it with intelli-sense through qualifying the module with Module1..
If you're starting from fresh, you can do the following:
for all your private sub function, name them into a standard format but as public function at the moment, for e.g.:
Public sub iamprivate_calDate ()
Public sub iamprivate_getsetfunction()
...
after you're completed with your macros, simply find and replace all your "Public sub iamprivate" into "Private sub " in your editor.

Is there a way to determine the value of a property on a form that calls a method in a seperate class library

Specifically aimed at winforms development.
I suspect that the answer to this is probably No but S.O. has a nice way of introducing me to things I didn't know so I thought that I would ask anyway.
I have a class library with a number of defined methods therein. I know from personal experimentation that it is possible to get information about the application within which the class library is referenced. What I would like to know is whether it would be possible to get information about the value of a property of a control on a form when a routine on that form calls a method in my class library without passing a specific reference to that form as a parameter of the method in the class library?
So purely as an example (because it's the only thing I can think of off the top of my head). Is there a way that a message box (if it had been so designed to do so in the first place) could 'know' from which form a call to it had been made without that form being specifically referenced as a parameter of the message box in the first place?
Thanks for any insights you might have.
To address the example of the MessageBox, in many of the cases you can use the active form. You can retrieve it by using Form.ActiveForm. Of course, as regards the properties that you can request, you are limited to the properties provided by the Form or an interface that the Form implements and that the method in the other assembly also knows. To access other properties you can use Reflection, but this approach would neither be straightforward nor would it be clean.
In a more general scenario, you could provide the property value to the method as a parameter. If it is to complex to retrieve the value of the property and the value is not needed every time, you can provide a Func(Of TRESULT) to the method that retrieves the value like this (sample for an integer property):
Public Sub DoSomethingWithAPropertyValue(propValFunc As Func(Of Integer))
' Do something before
If propertyValueIsNeeded Then
Dim propVal = propValFunc()
End If
' Do something afterwards
End Sub
You call the method like this:
Public Sub SubInForm()
Dim x As New ClassInOtherAssembly()
x.DoSomethingWithAPropertyValue(Function() Me.IntegerProperty)
End Sub
I kind of question your intentions. There's no problem sending the information to a function or the constructor.
Instead of giving the information to the class, the class would ask for the information instead using an event.
Module Module1
Sub Main()
Dim t As New Test
AddHandler t.GetValue, AddressOf GetValue
t.ShowValue()
Console.ReadLine()
End Sub
Public Sub GetValue(ByRef retVal As Integer)
retVal = 123
End Sub
End Module
Class Test
Public Delegate Sub DelegateGetValue(ByRef retVal As Integer)
Public Event GetValue As DelegateGetValue
Public Sub ShowValue()
Dim val As Integer
RaiseEvent GetValue(val)
Console.WriteLine(val)
End Sub
End Class

Vb.Net scoping question - private fields

I have been looking at a class that has a method that accepts a parameter that is of the same type of the class containing the method.
Public Class test
private _avalue as integer
Public Sub CopyFrom(ByVal from as test)
_avalue = from._avalue
End Sub
End Class
When used in code
a.CopyFrom(b)
It appears that instance "a" has visibility to the private members of the passed in instance "b" and the line
_avalue = from._avalue
runs without error copying the private field from one object instance to the other.
Does anyone know if this is by design. I was under the impression that a private field was only accessible by the instance of the object.
The private scope is related to the type not the instance. So yes, this is by design.
The class test has knowledge about the private parts of itself, so it can use those parts also on other instances of the same type.
You are writing something similar to to a copy constructor.
Since the copying method/function is being written inside of the same class, it will have access to private variables of any instance of its own class.

Shared method in VB.NET cannot handle this why?

(I tried with this question but this code isolates the problem better.)
I have this code:
Public Shared Sub PopulateTextFields(ByRef stuffList As List(Of Stuff))
Dim aStuff As New Stuff
For Each aStuff In stuffList
DoStuff(aStuff)
Next
End Sub
Private Sub DoStuff(ByRef theStuff as Stuff)
....
End Sub
I get the following error highlighting DoStuff(aStuff):
Cannot refer to an instance member of
a class from within a shared method or
shared member initializer without an
explicit instance of the class.
Didn't I get an explicit instance of Stuff when I wrote the Dim statement?
Don't understand what's wrong. Thanks in advance!
I think the problem lies with the Subroutine DoStuff. If both your subs lie in the same class, you are trying to refer to DoStuff from within PopulateTextFields, which is a shared sub.
In order to achieve this, you need to declare DoStuff as Shared as well.
Yes you did, but you aren't referencing aStuff you are trying to call it on the static implementation of the class, furthermore you are resetting aStuff to a separate instance through each loop iteration.. change your code to:
Public Shared Sub PopulateTextFields(ByRef stuffList As List(Of Stuff))
Dim aStuff As New Stuff
For Each aStuff In stuffList
aStuff.DoStuff(aStuff)
Next
End Sub
Private Sub DoStuff(ByRef theStuff as Stuff)
....
End Sub
And it should work, but maybe not as expected, I don't really know your intent of having a private member that handles changing a separate reference of it's own type.
It may be appropriate to change the signature of DoStuff to:
Private Sub DoStuff()
....
'Use the Me reference here to change myself
....
End Sub
and then call it as:
aStuff.DoStuff() 'Will modify this instance
You didn't share which type these methods belong to. From your confusion, I'm guessing it's part of the "Stuff" class. But it doesn't really matter. It sounds like you're forgetting one of two things:
Creating an instance of the type in the shared method doesn't somehow attach the shared method to that instance. You could create 10 or 1000 instances in the method, after all.
Passing an instance as a parameter doesn't associate the function with an instance. A parameter is not a call site.
Either way, it comes down to providing an instanced call site. Your DoStuff function is not shared, and so the compiler thinks it needs access to state provided by a specific instance of your type. That instance is the method's call site. You either need an instance of the type to call it from: SomeInstance.DoStuff(aStuff) , or if the method doesn't really need access to any type state you need to mark it shared and call it like this: Stuff.DoStuff(aStuff)