How to implement the overload of class variables in VB.NET

xiaoxiao2021-03-20  210

Overload variables in VB.NET

The overload function is very normal, but sometimes it needs overload variables, such as the following example.

Class Person

Public Name As String

END CLASS

Class Orgnization

Public Head As Person

...

END CLASS

Orgnization is a class that represents an organization, which has a Head member that represents the leader of this organization, which is a Person type.

Now I want to derive a class School from ORGNIZation, and use it has defined a functional function, but I am not satisfied with the Person type, because it's too little, only one name, I want to add an AGE field, then I What should I do?

In C , this is a very simple matter, just design the Orgnization into a template class, but in VB, this is a big problem - because I actually need to overload the HEAD variable.

In vb.net introduces Delegate, and hides Shadows Concept, if they combine them with the overload function, you can achieve the overload of the variable, the idea is like this:

1. Delegate makes the function can be passed to another function as a parameter;

2, the function is returned, and can be overloaded, if I let a variable always be pointed out by a function, then reload this function, you can overload this variable, but there is One premise, that is, the variable that needs to be overloaded must be declared as an Object type or other base class type (if you can determine the derived type of this base class type);

3, hide the base class variable that needs to be overloaded by shadows, and then define a derived variable of the same name in the derived class (type is a derived type of the type of variable being overloaded);

4. In the base class, all variables to be retrieved are not directly referred to, but reference a delegate type function pointing to it;

5. In the derived class, the function of this delegate type is overloaded, which is changed to achieve overloading of the base class variable.

example:

Namespace P

Public Class Person

Public Name As String

END CLASS

Public class orgnization 'base class

Public head as new person 'Head needs to be overloaded

Protected delegate function f_head () as Person

Protected Overridable Function GetHead () AS Person 'Key: This function always points to the head class of Head,

And can be overloaded

Return HEAD

END FUNCTION

Public Sub Displayhead ()

MsgBox (). Name.toString ()) 'Indirect calls Head variable

There is a must pay attention to where getHead must bring parentheses.

If you don't want to be awkward, it is very simple - designing gethead into

Attributes

End Sub

'...

END CLASS

Public class schoolhead 'head will be overloaded into this type

Inherits Person

Public Age As Integer

END CLASS

Public Class School

Inherits OrgnizationPublic Shadows Head As New Schoolhead 'first hides the head of the base class with Shadows, then declare a new Head

Protected Overrides Function GetHead () AS Person 'Reserves this function and thus all the Head of the base class

Call, it turned out to be mapped to the base class GetHead

Function, now mapped to the derived class

function. And this function is to derived

HEAD variable, so that all functions of the base class

The call to the HEAD is all redirected to the derived

Type of HEAD

Return HEAD

END FUNCTION

'...

END CLASS

Now do code code to test:

Public SUB T

Dim p as new p.school

p.Head.name = "lj"

p.Head.Age = 100

p.displayhead ()

End Sub

The results showed that the LJ, indicating that the DisplayHead finally acts on the SHADOWS semantic description, and the total function of the base class is hidden on the base class, but here uses a small skill, implementation Redirection, enable the function of the base class to the members of the derived class.

From the perspective of the derived class, the heavy-duty Head does not cost too much code, just add a heavy-duty function, the key is that the base category should be designed - should have the old saying: the former people planted trees, the future generations

This example illustrates the most basic idea of ​​overloading variables, but it also has obvious shortcomings:

1. GetHead () of the derived class is the Person type, not the Schoolhead type, and thus call this function each time in the derived class function, you must also use CType to convert it, it is very inconvenient. But if you think that the HEAD variable of this derived class will not be inherited, you can use the getHead function, but it is directly using the Head of the class. But if you think that the HEAD of this derived class is likely to be overloaded, there is no way to convert. For frequent use, of course, a private function (or attribute) can be designed, use it to package CType, and return to the Schoolhead type, and in other derived class functions, use this private function to turn one, this can be Write code easily;

2, if the base class has a public property head (of course, it may be a function), it passes the HEAD object, which is a bit trouble, because the derived class requires the instance of the Schoolhead type. This also has a way to resolve: Use a shadows to hide the public property of the base class, and design a HEAD property of the same name, in the GET segment, you can write this:

Return HEAD

If there are other useful code in the base class, you can add a few words in front: Head = mybase.head ...

3. Although this method is functional, it is necessary to turn several functions per call (whether it is inside or outside, or outside), the program performance is obviously affected, so if it is not special It is not necessary to do so, it is better to stick to it.

4, serialization problem. In this example, if serialization is serialized for School, it will be found to resolve the problem when declaring the serializer, but as long as the Head member in the base class Orgnization is declared as protected to protected. In fact, it is not only this application, as long as you use shadows to hide the base variable, and this base class variable is a PUBLIC type, this error will appear. I guess the reason: Although the base class variable is hidden, it does not exist, in fact it is still in memory, but the serializer does not find this problem, it only knows the public variables to detect the public variables. As a result, there were two variables of the same name, so I didn't know what to do, only an error. However, just declare this variable as private or protected, it is also a shortcomings. Further:

What if you want to overload an array?

There is no problem, the idea is the same.

Now some of the above examples have been modified:

Public class Orgnization '

Public head (1) as person 'Head is changed to array

Protected delegate function f_head () as person () 'Note: It is very strange, Person does not bring parentheses.

You can also run through!!

Protected overridable readonly property gethead () as person () 'Return Value change to array type

Get

Return HEAD

END GET

End Property

Public function displayhead ()

MsgBox (0) .Name.toString ()) 'Here is a different write method, and the properties are better.

END FUNCTION

Sub new ()

Head (0) = New Person 'Don't forget to create an instance

Head (1) = New Person

End Sub

'...

END CLASS

Calibrate the students below:

Public Class School

Inherits Orgnization

Public Shadows Head (1) as schoolhead 'also declares as an array

Protected Overrides Readonly Property GetHead () As Person () '

Get

Return HEAD

END GET

End Property

'...

Sub new ()

Head (0) = new schoolhead 'is still the same

HEAD (1) = new schoolheadhead

End Sub

END CLASS

Test code:

Sub T

DIM P as new school

HEAD (0) .Name = "lj"

HEAD (0) .age = 100

Displayhead ()

MSGBOX ("OK")

End Sub

The result is correct, display "LJ", explaining the array of DISPLAYHEADs or calls, not base classes.

转载请注明原文地址:https://www.9cbs.com/read-130362.html

New Post(0)