There are just three ways to organize a VB.NET application.
只有三种方法来组织VB.NET应用程序。
- Modules 模组
- Structures 结构体
- Classes 班级
But most technical articles assume that you already know all about them. If you're one of the many who still have a few questions, you could just read past the confusing bits and try to figure it out anyway. And if you have a lot of time, you can start searching through Microsoft's documentation:
但是大多数技术文章假定您已经了解它们。 如果您是仍然有几个问题的众多人中的一员,则可以阅读一些令人困惑的内容,然后尝试找出答案。 如果您有很多时间,可以开始搜索Microsoft的文档:
- "A Module is a portable executable file, such as type.dll or application.exe, consisting of one or more classes and interfaces." “模块是一种可移植的可执行文件,例如type.dll或application.exe,由一个或多个类和接口组成。”
- "A Class statement defines a new data type." “ Class语句定义了新的数据类型。”
- "The Structure statement defines a composite value type that you can customize." “ Structure语句定义了可以自定义的复合值类型。”
Right, then. Any questions?
是的 任何问题?
To be a bit more fair to Microsoft, they have pages and pages (and more pages) of information about all of these that you can wade through. And they have to be as exact as possible because they set the standard. In other words, Microsoft's documentation sometimes reads like a law book because it is a law book.
为了对Microsoft更公平一点,它们具有页面和页面(以及更多页面)有关您可以浏览的所有信息的页面。 而且它们必须尽可能精确,因为它们设置了标准。 换句话说,Microsoft的文档有时读起来就像一本法律书籍,因为它是一本法律书籍。
But if you're just learning .NET, it can be very confusing! You have to start somewhere. Understanding the three fundamental ways that you can write code in VB.NET is a good place to start.
但是,如果您只是学习.NET,可能会非常混乱! 你必须从某个地方开始。 了解在VB.NET中编写代码的三种基本方式是一个不错的起点。
You can write VB.NET code using any of these three forms. In other words, you can create a Console Application in VB.NET Express and write:
您可以使用这三种形式中的任何一种来编写VB.NET代码。 换句话说,您可以在VB.NET Express中创建控制台应用程序并编写:
Module Module1Sub Main()MsgBox("This is a Module!")End SubEnd ModuleClass Class1Sub Main()MsgBox("This is a Class")End SubEnd ClassStructure Struct1Dim myString As StringSub Main()MsgBox("This is a Structure")End SubEnd Structure
模块Module1Sub Main()MsgBox(“这是一个模块!”)结束子级ModuleClass Class1Sub Main()MsgBox(“这是一个类”)结束SubEnd ClassStructure Struct1Dim myString as StringSub Main()MsgBox(“这是一个结构”)端子端结构
This doesn't make any sense as a program, of course. The point is that you don't get a syntax error so it's "legal" VB.NET code.
当然,这对于程序没有任何意义。 关键是您不会遇到语法错误,因此它是“合法的” VB.NET代码 。
These three forms are the only way to code the queen bee root of all of .NET: the object. The only element that interrupts the symmetry of the three forms is the statement: Dim myString As String. That has to do with a Structure being a "composite data type" as Microsoft states in their definition.
这三种形式是编码所有.NET的女王蜂根的唯一方法:对象。 中断三种形式的对称性的唯一元素是语句: Dim myString As String 。 微软在其定义中指出,这与结构是“复合数据类型”有关。
Another thing to notice is that all three blocks have a Sub Main() in them. One of the most fundamental principals of OOP is usually called encapsulation. This is the "black box" effect. In other words, you should be able to treat each object independently and that includes using identically named subroutines if you want to.
要注意的另一件事是,所有三个块中都有一个Sub Main() 。 OOP的最基本原理之一通常称为封装 。 这就是“黑匣子”效应。 换句话说,您应该能够独立对待每个对象,并且如果需要的话,还可以使用名称相同的子例程。
班级 ( Classes )
Classes are the 'right' place to start because, as Microsoft notes, "A class is a fundamental building block of object-oriented programming (OOP)." In fact, some authors treat modules and structures as just special kinds of classes. A class is more object oriented than a module because it's possible to instantiate (make a copy of) a class but not a module.
类是“正确”的起点,因为正如微软指出的那样,“类是面向对象编程(OOP)的基本构建块。” 实际上,有些作者将模块和结构视为特殊的类。 类比模块更面向对象,因为它可以实例化 (而不是实例化 )一个类而不是模块。
In other words, you can code ...
换句话说,您可以编码...
Public Class Form1Private Sub Form1_Load( _ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles MyBase.LoadDim myNewClass As Class1 = New Class1myNewClass.ClassSub()End SubEnd Class
公共类Form1Private子Form1_Load(_ByVal发送者作为System.Object,_ByVal e作为System.EventArgs)_Handles MyBase.Load Dim myNewClass as Class1 = New Class1 myNewClass.ClassSub()End SubEnd Class
(The class instantiation is emphasized.)
(强调类的实例化。)
It doesn't matter whether the actual class itself, in this case, ...
在这种情况下,实际的类本身是否无关紧要……
Public Class Class1Sub ClassSub()MsgBox("This is a class")End SubEnd Class
公共类Class1Sub ClassSub()MsgBox(“这是一个类”)结束SubEnd类
... is in a file by itself or is part of the same file with the Form1 code. The program runs exactly the same way. (Notice that Form1 is a class too.)
...本身在文件中,或者与Form1代码在同一文件中。 该程序以完全相同的方式运行。 (请注意, Form1也是一个类。)
You can also write class code that behaves much like a module, that is, without instantiating it. This is called a Shared class. The article "Static" (that is, "Shared") versus Dynamic Types in VB.NET explains this in much more detail.
您也可以编写行为类似于模块的类代码,即无需实例化它。 这称为共享类。 VB.NET中相对于动态类型的文章“静态”(即“共享”)对此进行了更详细的说明。
Another fact about classes should also be kept in mind. Members (properties and methods) of the class only exist while the instance of the class exists. The name for this is scoping. That is, the scope of an instance of a class is limited. The code above can be changed to illustrate this point this way:
关于类的另一个事实也应牢记。 该类的成员 (属性和方法)仅在该类的实例存在时才存在。 其名称为作用域 。 即,类实例的范围是有限的。 可以更改上面的代码以这种方式说明这一点:
Public Class Form1Private Sub Form1_Load( _ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles MyBase.LoadDim myNewClass As Class1 = New Class1myNewClass.ClassSub()myNewClass = NothingmyNewClass.ClassSub()End SubEnd Class
公共类Form1Private子Form1_Load(_ByVal发送者作为System.Object,_ByVal e作为System.EventArgs)_Handles MyBase.LoadDim myNewClass作为Class1 = New Class1myNewClass.ClassSub()myNewClass = NothingmyNewClass.ClassSub()End SubEnd Class
When the second myNewClass.ClassSub() statement is executed, a NullReferenceException error is thrown because the ClassSub member doesn't exist.
当执行第二个myNewClass.ClassSub()语句时,将抛出NullReferenceException错误,因为ClassSub成员不存在。
模组 ( Modules )
In VB 6, it was common to see programs where most of the code was in a module (A .BAS, file rather than, for instance, in a Form file such as Form1.frm.) In VB.NET, both modules and classes are in .VB files. The main reason modules are included in VB.NET is to give programmers a way to organize their systems by putting code in different places to fine tune the scope and access for their code. (That is, how long members of the module exist and what other code can reference and use the members.) Sometimes, you may want to put code into separate modules just to make it easier to work with.
在VB 6中,通常会看到程序的大部分代码都在模块中(一个.BAS文件,而不是例如Form1.frm之类的Form文件中)。在VB.NET中,这两个模块和类在.VB文件中。 原因主要模块包括在VB.NET是给程序员的方式通过将代码在不同的地方进行微调的范围和访问他们组织自己的系统代码 。 (即,该模块的成员存在多长时间,还有哪些其他代码可以引用和使用这些成员。)有时,您可能希望将代码放入单独的模块中,以使其更易于使用。
All VB.NET modules are Shared because they can't be instantiated (see above) and they can be marked Friend or Public so they can be accessed either within the same assembly or whenever they're referenced.
所有VB.NET模块都是共享的,因为它们无法实例化(请参见上文),并且可以将它们标记为Friend或Public,以便可以在同一程序集中或被引用时对其进行访问。
结构体 ( Structures )
Structures are the least understood of the three forms of objects. If we were talking about "animals" instead of "objects," the structure would be an Aardvark.
在三种形式的对象中,对结构的了解最少。 如果我们谈论的是“动物”而不是“对象”,则其结构将是Aardvark 。
The big difference between a structure and a class is that a structure is a value type and a class is a reference type.
结构和类之间的最大区别是结构是值类型,而类是引用类型 。
What does that mean? I'm so glad you asked.
那是什么意思? 我很高兴你问。
A value type is an object that is stored directly in memory. An Integer is a good example of a value type. If you declared an Integer in your program like this ...
值类型是直接存储在内存中的对象。 整数是值类型的一个很好的例子。 如果您在程序中这样声明一个Integer ...
Dim myInt as Integer = 10
将myInt昏暗为整数= 10
... and you checked the memory location stored in myInt, you would find the value 10. You also see this described as "being allocated on the stack".
...,然后检查了存储在myInt中的内存位置,您会发现值10。您还看到此内容被描述为“正在堆栈中分配”。
The stack and the heap are simply different ways of managing the use of computer memory.
堆栈和堆只是管理计算机内存使用的不同方法。
A reference type is an object where the location of the object is stored in memory. So finding a value for a reference type is always a two step lookup. A String is a good example of a reference type. If you declared a String like this ...
引用类型是一个对象,对象的位置存储在内存中。 因此,查找引用类型的值始终是两步查找。 字符串是引用类型的一个很好的例子。 如果您声明这样的字符串 ...
Dim myString as String = "This is myString"
Dim myString as String =“这是myString”
... and you checked the memory location stored in myString, you would find another memory location (called a pointer - this way of doing things is the very heart of C style languages). You would have to go to that location to find the value "This is myString". This is often called "being allocated on the heap". The stack and the heap
...然后检查了存储在myString中的内存位置,您将找到另一个内存位置(称为指针 -这种处理方式是C样式语言的核心)。 您将必须转到该位置以找到值“ This is myString”。 这通常称为“在堆上分配”。 堆栈和堆
Some authors say that value types aren't even objects and only reference types can be objects. It's certainly true that the sophisticated object characteristics like inheritance and encapsulation are only possible with reference types. But we started this whole article by saying that there were three forms for objects so I have to accept that structures are some sort of object, even if they're non-standard objects.
一些作者说,值类型甚至不是对象,只有引用类型可以是对象。 当然,只有引用类型才可以实现诸如继承和封装之类的复杂对象特性。 但是,我们从整篇文章开始说,对象有三种形式,因此我必须接受结构是某种对象,即使它们是非标准对象也是如此。
The programming origins of structures go back to file-oriented languages like Cobol. In those languages, data was normally processed as sequential flat files. The "fields" in a record from the file were described by a "data definition" section (sometimes called a "record layout" or a "copybook"). So, if a record from the file contained:
结构的编程起源可追溯到面向文件的语言,例如Cobol。 在这些语言中,数据通常作为顺序的平面文件处理。 文件的记录中的“字段”由“数据定义”部分(有时称为“记录布局”或“副本”)描述。 因此,如果文件中的记录包含:
1234567890ABCDEF9876
1234567890ABCDEF9876
The only way you would know that "1234567890" was a phone number, "ABCDEF" was an ID and 9876 was $98.76 was through the data definition. Structures help you accomplish this in VB.NET.
通过数据定义,您唯一会知道“ 1234567890”是电话号码,“ ABCDEF”是ID和9876是$ 98.76的唯一方法。 结构可以帮助您在VB.NET中完成此任务。
Structure Structure1<VBFixedString(10)> Dim myPhone As String<VBFixedString(6)> Dim myID As String<VBFixedString(4)> Dim myAmount As StringEnd Structure
结构Structure1 <VBFixedString(10)>将myPhone设置为字符串<VBFixedString(6)>将myID设置为字符串<VBFixedString(4)>将myAmount设置为StringEnd结构
Because a String is a reference type, it's necessary to keep the length the same with the VBFixedString attribute for fixed length records. You can find an extended explanation of this attribute and attributes in general in the article Attributes in VB .NET.
因为String是引用类型,所以对于固定长度记录,必须使长度与VBFixedString属性保持相同。 您可以在VB .NET中的属性一文中找到有关此属性和属性的扩展说明。
Although structures are non-standard objects, they do have a lot of capability in VB.NET. You can code methods, properties, and even events, and event handlers in structures, but you can also use more simplified code and because they're value types, processing can be faster. For example, you could recode the structure above like this:
尽管结构是非标准对象,但它们在VB.NET中确实具有很多功能。 您可以对结构中的方法,属性甚至事件和事件处理程序进行编码,但也可以使用更简化的代码,并且由于它们是值类型,因此处理速度可以更快。 例如,您可以像这样重新编码上面的结构:
Structure Structure1<VBFixedString(10)> Dim myPhone As String<VBFixedString(6)> Dim myID As String<VBFixedString(4)> Dim myAmount As StringSub mySub()MsgBox("This is the value of myPhone: " & myPhone)End SubEnd Structure
结构Structure1 <VBFixedString(10)>将MyPhone设置为字符串<VBFixedString(6)>将myID设置为字符串<VBFixedString(4)>将myAmount设置为StringSub mySub()MsgBox(“这是myPhone的值:”&myPhone)结束副端结构
And use it like this:
并像这样使用它:
Dim myStruct As Structure1myStruct.myPhone = "7894560123"myStruct.mySub()
将myStruct变暗为Structure1myStruct.myPhone =“ 7894560123” myStruct.mySub()
It's worth your time to play around with structures a bit and learn what they can do. They're one of the odd corners of VB.NET that can be a magic bullet when you need it.
值得您花一些时间研究一下结构并了解它们可以做什么。 它们是VB.NET的奇特角落之一,当您需要时可以成为魔术子弹。
翻译自: https://www.thoughtco.com/modules-structures-and-classes-3424349