Declaring an object without using the namespace of the class - vb.net

I have a class library project named MyWidget, with the only class being named MyWidget.
In another project, I've added a reference to my class library, and in my new class, I've tried typing in
Imports MyWidget
and
Imports MyWidget.MyWidget
However, later in my class when I try to create a new reference, Visual Studio is not allowing me to type in this:
Private widget As MyWidget
However, Visual Studio is giving me a "Type Expected." error and forcing me to also include the namespace, like so:
Private widget As MyWidget.MyWidget
I read the MSDN documentation regarding the Imports statement. I should be able to leave off the namespace when declaring the object because I have the imports statement at the top of the program. I've tested this with standard namespaces, and it works fine, but when I try it out with my class, it doesn't.
Am I missing something in the MyWidget class that will allow me to leave off the namespace when declaring the object?
I also tried renaming the namespace to MyClasses, thinking maybe that Visual Studio was getting the namespace confused with the class. However, even with
Imports MyClasses.MyWidget
I still get an error when trying to define a MyWidget object without the MyClasses Namespace.

Since the Namespace and Class have the same name the compiler gets confused when you try to instantiate MyWidget, despite the Imports statement. Just because there is an Imports statement, doesn't mean you can't fully quanlify a type (even if you have Imports System.IO.File, you can still call System.IO.File.WriteAllText), thus the confusion on the compilers end. An alternative would be to use an Alias.
Imports AWidget = MyWidget.MyWidget
Then..
Dim objWidget As New AWidget

It appears that the issue was the namespace and the class having the same name. After changing the namespace to MyClasses and the class to MyWidget, the following statements worked:
Imports MyClasses
...
Private widget as MyWidget

Related

Duplicated Namespace is created on dll

I'm creating a class library in VS2019 (VB.NET).
In the project properties, I used this root namespace: Customer.App.Classlibrary
When I'm compiling and using this library in another project, I need to import it as
Import Customer.App.Classlibrary.Customer.App.Classlibrary
The root namespace is duplicated....
Any suggestions???
Unlike c#, in vb.net you don't need a namespace around your class, rather all vb.net code starts in the root namespace without specifying one. So when you have written your function to be used like this
Namespace Customer.App.Classlibrary
Public Module MyStaticCLass
Public Sub Foo()
End Sub
End Module
End Namespace
the namespace Customer.App.Classlibrary is added to the root namespace.
and your namespace becomes RootNamespace.ClassNamespace = Customer.App.Classlibrary.Customer.App.Classlibrary
and you need to do
Imports Customer.App.Classlibrary.Customer.App.Classlibrary
The fix: just remove the namespace from your class definition
'Namespace Customer.App.Classlibrary
Public Module MyStaticCLass
Public Sub Foo()
End Sub
End Module
'End Namespace
and the imports will simply be
Imports Customer.App.Classlibrary
It might be a better idea to specify the root namespace to Customer and you can put your class in Namespace App.Classlibrary which will have a similar effect, with the added benefit of being able to separate classes in the same assembly into more granular namespaces. This depends on your desired design.

Prevent public module variables from being globally accessible

If I have the following code:
Public Module MyModule
Public MyVariable As Integer
End Module
VB.NET allows unqualified access to the variable (field) from anywhere in the project, which means I can write the following anywhere in the project1:
MyVariable = 5
Is there any way to disable this behavior on a specific type, such that I can only access the variable via the module name?
MyModule.MyVariable = 5
NB. I know I can use a standard class, and the Shared keyword on all the members:
Public Class MyModule
Public Shared MyVariable
End Class
1. If I use Friend instead of Public on the module, this functionality will only apply to the assembly, not the entire project.
First, those need not be Public to get the global variable behavior. Friend will also work:
The Friend keyword in the declaration statement specifies that the elements can be accessed from within the same assembly, but not from outside the assembly.
If you put your module in a different namespace, you can get the behavior you are after:
Namespace Plutonix
Friend Module GlobalVars
Friend MyVariable As Int32
End Module
End Namespace
Unfortunately, VB will prepend the project Namespace to whatever you use so your import would be something like:
Imports PrjNamespace.Plutonix
But then you get what you are after:
GlobalVars.MyVariable = 9
Personally, I think the class version or as few global variables as possible is better

Override Import's takeover of Collection?

I'm trying to create a new Collection -
Dim theSet as New Collection
but, I am using the Textsharp PDF creator in my project -
Imports iTextSharp.text
Imports iTextSharp.text.pdf
and Textsharp apparently creates it's own "collection" Namespace, removing the VB.NET one.
Is there a way to override this and use the VB.NET Collection statement?
Thanks
There is not much you can do about a library polluting the namespace with common words like that. It has a Java background and counted on a case-sensitive language. You'll have to help the compiler by being explicit that you meant to use the VB.NET Collection class and not the iTextSharp.pdf.text.collection namespace. Either type out of the full class name to disambiguate:
Dim theSet as New Microsoft.VisualBasic.Collection
Or add an alias:
Imports VBCollection = Microsoft.VisualBasic.Collection
...
Dim theSet as New VBCollection
That same aliasing trick works on the library as well:
Imports Pdf = iTextSharp.text.pdf
And you'll have to prefix Pdf. whenever you want to reference a type from that namespace.

Use namespace alias in subsequent Imports?

I have a huge library with lots of namespaces and classes, nested to >10 levels deep. In most projects I will be using only one of the most nested namespaces at a time, so there is some kind of root, above which I will not Import. For example, the object I need lies within:
Imports MyObject = ns1.ns2.ns3.ns4.ns5.MyObject
And another one in:
Imports MyOtherObject = ns1.ns2.ns3.ns4.ns5.ns6.MyOtherObject
Problem is that ns1 and other nsX can be very long name, so the whole lines goes way off screen and it's hard to follow. I was hoping you could declare an alias like this:
Imports MyRoot = ns1.ns2.ns3.ns4.ns5
And then use the above:
Imports MyObject = MyRoot.MyObject
Imports MyOtherObject = MyRoot.ns6.MyOtherObject
But it does not work like this, i.e. Imports do not see each other.
I tried using project-wide settings - same behavior. Is there a solution or a workaround?
I was thinking maybe it's possible to package namespaces into another namespace? (similar to how My works, but I could not find any good source on how to implement this)

Why is one class not able to recognize the public member variable of another class

I have two classes as follows
Public Class A_one 'This project does not have a dll generated even after a build. Any reason why ?
Public Structure struct
Dim xyz as String
Dim p as String
End Structure
Public Sub xyz(...)
ClassB_one_Obj = New ClassB_one_Obj(SampleStruct)
ClassB_one_Obj.send_struct(sampleStruct)
End Sub
Public Class B_one 'In a different project
Public Sub send_struct(ByVal sampleStruct As A_one.struct) 'Throwing error here **"Type A_one.struct not defined"**
Can anybody explain why i'm getting the error. Is it because I have not added the dll reference of class A_one in Class B_one ?
I tried to add the reference dll of A_one , but was not able to find it either in the obj/bin folders .
Can anybody point me to a work around ?
EDIT/UPDATE : Figured that the class A_one which is the main executable creates objects of Class B_one and that is the reason we can't create an object of class A_one in B_one, since there is a deadlock-like situation.
Is it true that we can't create an object of the main class ( start-up class ) from another class ?
Yes, the error is because project B is not referencing project A, so it doesn't know anything about that type.
From withing Visual Studio, go to the properties of project B, References, Add. If project A is in the same solution as B, add it as as a Project/Solution reference, otherwise you can browse for the DLL. If you use the DLL method, you will have to ensure that the project type of project A is set to be a Class Library and that it has been successfully built. If its not set to be a Class Library project, it will most likely have built as an EXE file (you can add a reference to an EXE file as well, if you need project A to stay as a stand-alone executable).