Take a collection class overview .NET Collectes and related technologies via C #

zhaozj2021-02-17  51

Author: Firebird

Redbirdli@hotmail.com

Overview: In a real objective development project, we usually abstract commonly used business entities as specific classes, such as EMPLOYEEEEEE, Customer, Contact, etc., and there is a corresponding association or dependency between most classes, such as Employee and Customer generate associations via Contact, Contact exists depending on Employee and Customer. In the actual object application module, there may be such a need: obtain a set of customer objects (ie, instances of the Customers collection class, such as Customers), pointing to one of the Customer objects (such as Customers [i]), by accessing this Customer object Attribute Name (Customers [i] .name) and Contacts (such as Customers [i] .contacts "to query the customer's name and contact with the customer, even traversing the Contacts object, find the customer's contact summary (ie Customers. [i] .contacts [x] .summary). To meet the needs of the above collection class, it is not difficult to discover the platform of the platform, Net Framework. NET provides a series of classes that implement collection functions under the Collections namespace, and the developers provide flexible and diverse options in accordance with the applicable environment: such as accessible by indexing uses extensive ArrayList and StringCollection; usually released after retrieval First-out Queue and the first outstack; Access HashTable, SortedList, ListDictionary and StringDictionary via an element key; NameObjectCollectionBase and NameValueCollection, which are accessed by an index or via an element key; and a collection class The Array class that is implemented under System.Array. This article will analyze the differences and applicable environments with representative "set classes", to analyze and master the relevant technologies, hoping to work for everyone's learning and development work. The role of throwing brick 引 (Note: the author's debug operation environment is .NET Framework SDK 1.1).

1

. Adopt

CollectionBase

Abstract basic class inheritance

Customers

Collection class:

First, you need to create a simple class Customer for the collection element:

///

/// Describe a class of basic information

///

Public Class Customer

{

///

/// customer's name

///

Public String Name;

///

/// Describe the collection class of all customer contact information

///

//

Public Contacts Contacts = New Contacts ();

///

/// without parameters Customer class constructor

///

Public Customer ()

{

System.Console.writeline ("Initialize Instance Without Parameter);

}

///

/// Customer class constructor with parameters ///

Public Customer (String Name)

{

Name = name;

System.Console.writeline ("Initialize Instance with Parameter);

}

}

The above is a simple framework of the Customer class, and the practical Customer class may have more fields, properties, methods, and events. It is worth noting that in the custom of the Customer class, the inline formation of the Contacts collection class is also implemented in the form of the Contacts collection class, which ultimately forms the interface form of Customer.Contacts [i], but this is not the most ideal set class association method, temporarily It comes with the analysis, which will be analyzed later. The code of this class is focused on the framework of a simple class (relative to the concept of the collection class); in addition, the class also overloads the class constructor, which is to declare the class. The instance is provided with an Name parameter or without parameters.

Next, we will see our first set class implementation, based on the Customers class that is implemented from the CollectionBase class:

///

/// Customers is a collection class implementation of Customer, inheriting from CollectionBase

///

Public Class Customers: System.Collections.collectionBase

{

Public Customers ()

{

}

///

/// 自己 实 实 的 a a

///

///

Public Void Add (Customer Customer)

{

List.Add (Customer);

}

///

/// ourselves Remove method

///

///

Public Void Remove (int index)

{

IF (INDEX> Count - 1 || Index <0)

{

System.Console.writeline ("INDEX NOT VALID!");

}

Else

{

List.Removeat (Index);

}

}

}

Take the Customers collection class as an example, combined with collection auxiliary technology, I hope everyone can understand the following knowledge:

From

CollectionBase

Inherit implementation set class

The Customers class is inherited from CollectionBase, no longer need to declare a list object as a Customer collection container within a class, because the CollectionBase class has built a list object and has implemented important interfaces of ILIST, COUNT, CLEAR, REMOVEAT, etc. (For details, please refer to the CollectionBase member in MSDN, only the user will display the implementations of add, remove, indexof, insert, etc., and simply implement the entire parameter version of the Add method and the REMOVE method simply as an example. The implementation of this collection class has a simple and efficient feature, and CollectionBase has implemented a more complete function, and the implementator can expand its own function based on its basis.

Simple implementation of the indexer

We are used to operate the form of an operator is usually Array [i], and the set class can be considered as "an array of objects". In C #, help set classes implement the array index function is the indexer: public customer this [int index]

{

get

{

Return (Customer) List [Index];

}

}

After adding the above code to the Customers class, the Customers class read-only indexer with the Customer type returned value after the shaping index is converted to the Customer type returned by List [Index], and the user is used as Customers [i] .name In the way, you can access the name field of the i-i Customer object in the Customers collection. Is it very magical? The indexer code in the article does not consider the problem of the subscript, the cross-boundation method should refer to the similar REMOVE method. The author only implements the indexer's GET access, and the reasons for implementing SET access will be discussed below.

Item

Two implementations

Friends who have used VB must be familiar with Customers.itme (i) .Name, it implements the same role as the indexer, that is, through an index value to access specific objects in the collection, but Item is in C # What should I be implemented? The first thing you want to think should be attribute, but you will find that the attribute of C # will not support parameters, so you can't transfer the index value as a parameter. The method is to achieve:

Public Customer Item (INT INDEX)

{

Return (Customer) List [Index];

}

This Item method is already working, but why is it a compromised approach, because the access to Item will be the syntax form of Customers.Item (i) .name, and C # '[]' 作 数 标 标 标 风Unity, it is a bit awkward, but if you want to be unified on the grammat, even if you have some effects, there is no solution to the way? Please see the following code:

Public Customers Item

{

get

{

Return this;

}

}

This is an ITEM interface implemented in the property, but because the attribute of the C # does not support parameters, we return the Customers object itself, which is called the Customers indexer when calling the Customers object ITEM property, which has declined, but It is indeed a syntax style of Customers.Item [i] .Name. Compared to the implementation of these two Items, it is not difficult to conclusion: Items implemented in the form of an attribute that do not have parameters depend on the class's indexer, and if the class does not implement the indexer, the attribute will not be used; and due to access to Item Redirection to indexer performance will also decline; the only reason is: Unified C # index subscript access style; the benefits of adopting method implementation is exactly the opposite, in addition to the grammatical style, there is no dependency indexer, performance degradation problem. Fish and bear's paw are difficult to comply with, how to pay attention to the actual demand of development.

Compilation of intermediate language

Attribute

Applications

If you realize the standard indexer, you want to provide an interface called "item". There is an error when compiling. "The class 'windowsapplication1.customers' already contains" Item "definition, but except for the establishment of the indexer. You have nothing to do, where is the problem? We have to look for answers from .NET Middle Language IL, in the .NET command line environment or Visual Studio .net command prompt environment, enter iLDASM, run the .NET Framework MSIL disassemble tool, open in the main menu ' Loading only the indexer without the ITEM interface implementation. Net PE execution file can be compiled, and the Customers class is found by an intuitive tree structure map. You will accidentally find that the C # indexer is explained as an attribute called Item. The following is an indexer code that IL refactored is defined as an Item property: .property instance class windowsapplication1.customer

Item (INT32)

{

.get instance class windowsapplication1.customer windowsapplication1.customers :: get_item (int32)

} // End of property Customers :: item

The problem is final, the water falls, that is, the C # compiler 'written the indexer to interpret the indexer as an item named Item, and the ITEM interface we expects is exactly named, so the above-mentioned compilation error is inevitable. So, do we have a way to inform the compiler, don't name the inderator to the default Item? The answer is yes.

The solution is to declare the characteristics before the indexer implementation:

[System.Runtime.compilerServices.Indexername ("item")]]]]]

Define this indexername feature Tell the CSHARP compiler to compile the inderator into item instead of the default item, the indexer IL disassembly code after the modification is:

.property instance class windowsapplication1.customer

Item (INT32)

{

.get instance class windowsapplication1.customer windowsapplication1.customers :: get_item (int32)

} // End of property Customers :: item

Of course, you can define the generated attribute name of the indexer into other names, not limited to Item, as long as it is not the IL language to keep keywords. After named the indexer, you can freely join the interface named "Item".

The following is a debug code for the Customer class and the Customers class. In the author's Customers class, for the problem, it is found that the indexer with item-based character is established, an Items method and an ITEM property are implemented for three different elements. Accessing, actual project development, a class index function does not need to be repeated multiple times, may only implement an indexer or an indexer plus a form of Item is sufficient:

Public Class Calltest

{

Public static void main ()

{

Customers Custs = New Customers ();

System.console.writeline (Custs.count.tostring ()); // count property test

Customer ACUST = New Customer (); // will call a constructor without parameters

Acust.name = "peter";

CUSTS.ADD (ACUST); // Add method Tests System.Console.writeline (Custs.count.toString ());

System.console.writeline (Custs.Item [0] .Name); // Call the item property to get

Custs.Items (0) .Name = "hu"; // Call the items method to get

System.console.writeline (Custs [0] .name); // Call the indexer get

CUSTS.ADD (New Customer ("LinNet")); // // will call the constructor with the Name parameter

System.console.writeline (Custs.count.toString ());

System.console.writeline (Custs.Items (1) .Name); // Call the Items method to get

Custs.Item [1] .Name = "li"; // Call the items method to get

System.console.writeline (Custs [1] .name); // Call the indexer get

Custs.remove (0); // Remove method test

System.console.writeline (Custs.count.toString ());

System.console.writeline (Custs [0] .name); // Remove Validity Verification

CUSTS [0] .Name = "test passed"; // Call the indexer get

System.console.writeline (Custs.Item [0] .name);

Custs.clear ();

System.console.writeline (Custs.count.toString ()); // Clear Validity Verification

}

}

The output is:

0

Initialize Instance Without Parameter

1

Peter

Peterhu

Initialize Instance with Parameter

2

Linnet

Linnetli

1

Linnetli

Test passed

0

2

. Built

ArrayList

Object manual implementation set class:

Perhaps experienced programmers have already thought that you can build an array object in a class and you can implement the collection class by encapsulation through the package. The following is an implementation framework for the Contact element class and a Contacts collection class using this idea:

Public Class Contact

{

Protected string summary;

///

/// Customer contact instructions

///

Public String Summary

{

get

{

System.Console.writeline ("getter access");

Return summary; // do something,

AS Get Data from Data Source

}

set

{

System.console.writeline ("setter access");

Summary = value; // do something,

As Check Validity or Storage

}

}

Public contact ()

{

}

}

Public Class Contacts

{

Protected arraylist list;

Public Void Add (Contact Contact)

{

List.add (opportration);

}

Public Void Remove (int index)

{

IF (INDEX> List.count - 1 || Index <0) {

System.Console.writeline ("INDEX NOT VALID!");

}

Else

{

List.Removeat (Index);

}

}

Public Int Count

{

get

{

Return List.count;

}

}

Public Contact this [int index]

{

get

{

System.console.writeline ("Indexer getter Access");

Return (contact) list [index];

}

set

{

List [Index] = Value;

System.Console.writeline ("Indexer Setter Access");

}

}

Public contacts ()

{

List = new arraylist ();

}

}

Through the implementation of these two classes, we can summarize the following points:

use

ArrayList

s reason

When Contact is a built-in collection object, the ArrayList class is used without using the ARRAY class that is more familiar. The main reasons are: in existing. In the NET V1.1 environment, Although Array has exposed ilist.add, ilist.insert, ilist.remove, ilist.removeat, etc., which actually implements these interfaces, always triggered NotSupportedException, whether Microsoft is The implementation of future versions is unknown, but the current version. Net clearly does not support dynamic arrays, and the MS recommended by the Array size is that after copying the old array to the new array of expectations to the expected size, remove the old array, this shows that the time-consuming cost is around, and the collection cannot be satisfied. The class is at any time to delete an element; ArrayList has implemented a key interface for adding a collection class such as Add, Clear, Removeat, and has the ability to support read-only collection. In the top of the Contacts class, Easily package code, the collection class is easily implemented. Another problem is why we do not use the way to inherit from System.Collections.ArrayList in the case of Customers? Mainly due to the user directly exposed to the class of the ArrayList object, it will lead to illegal assignments. If the user calls the ArrayList.Add method, whether the input parameter type is Contact, the method will be successfully executed, the class cannot control and check the input. The type of object is consistent with the expectations, which is subject to the original intention of the CONTACT type object, and also left a great security hazard; and when the Contact object is acquired, if the mandatory type conversion is not, the Contacts element cannot be directly Contact type is used.

In the collection class

Set

During the implementation of the collection class, whether using the indexer or the "item" attribute of the same function as the indexer, it is inevitable to consider only Getter to form a read-only indexer, or simultaneously implement the completeness of Getter and Setter. Indexer Access. In the example class class Customers, the SETER of the indexer is not implemented, the read-only indexer is formed, but in the Customer class and the Customers class debug code, the author uses easy "Custs [0] .Name = "Test Passed" access form, in fact, the above sentence does not enter the setter of the Customers indexer, but will execute the Customers indexer getter get a Customer object, and then set this Customer's Name field (if Name If the element is attribute, the setter of the Customer class name attribute will be accessed. So what is the SETTER of the indexer to be used? In fact, only the set of setters that need to be dynamically covered when the entire element is running, such as "CUSTS [I] = New Customer ()" assigns a new Customer object to the Custs collection class already exists. One element, such access form will cause Customers's setter to be accessed, that is, the element object itself has reassigned, not just some of the properties of the existing object. That is, because the Customers class does not implement the SETTER of the indexer, the Customers class does not provide the "overlay" customer's method in the "overlay" customer collection. In this way, the ConTACTS class's indexer provides both Getter of the collection element, but also provides a setter of the collection element, that is, the Contacts class allows the user to dynamically update the Contact element. By running the following tests for both CONTACTS and Contact, you can clearly explain this problem: Public Class Calltest

{

Public static void main ()

{

Contacts cons = new contacts ();

Cons.add (new contact);

CONS [0] = new contact (); // Trigger Indexer Setter

CONS [0] .summary = "Mail Contact About Ticket";

System.console.writeline (cons [0] .summary);

}

}

The result of the outcome is:

Indexer Setter Access

Indexer getter Access

Setter Access

Indexer getter Access

Getter Access

Mail Contact About Ticket

Once the role of the indexer setter, the actual business characteristics, access rights control, and security decide whether to establish a setter mechanism for the indexer.

Property - powerful flexible field

Method for one

When I initially implemented the Customer class, we used a public field name to access the customer's name information, although it works normally, but we lack the control capabilities of the Name field, whether or not the class users use legal Effective field assignment, the value of the field will be modified; and there is no good mechanism, and real-time synchronization processing (such as data storage, notification related elements, etc.); in addition, the initialization of the field can only be placed The class constructor is completed, even if the Name field has never been accessed throughout the object lifecycle. Compared to the summary property implemented in the Contact class, it is not difficult to find that the properties have the advantages: attributes can be initialized while GET, if the attribute involves the way the network, database, memory, and threads, delay the initialization time It will play a certain optimization; the attribute package, the real customer contact description Summary is well protected, and when SET can be verified, verify the assignment operation; and before and after getter and setter, you can Perform data access and other related operations, this point is unlikely to be implemented. So we can conclude that in the environment where the field cannot meet the needs, the property is a more powerful alternative. In addition, the attribute integrates "GET" and "SET" two "methods", and the name of the unified natural interface is used, and the Object.GetAnything and Object.SetAnysthing syntax style of Java language are more pro-style (in fact, C # The attribute is only the re-package of the method, the Anything property with getter and setter is in .NET IL, it will be decomposed into a GET_ANAYTHING and SET_ANAYTHING that are called by the Anything property).

Collection class inline

In the original Customer class of the article, use the public field public contacts Contacts = new contacts () implements a collection class inline in the form of Customer. Contacts [], which is the most simple but lack of security-saving collection. As some advantages of the attributes described above, expose a public collection class interface in the form of attributes. When the access is actually accessed, it is a more properly perfect solution, such as The interface declaration of the set Contacts of the Customer class Contact is changed to:

Protected Contacts cons; // Real Contacts objects for encapsulated

Public Contacts Contacts // Exposed Contacts properties outside the class

{

get

{

IF (cons == null); new contacts ();

RETURN CONS;

}

set

{

CONS = VALUE;

}

}

In the end, Customers [i] .Contacts [x] .summary is successfully implemented.

Instantiated best time

. NET's type system is fully objective, all types are derived from system.object, depending on the individual features of the type, can be divided into two major camps of value types and reference types. Value types include structures (simple numeric and Boolean) and enumerations, reference types include class, arrays, delegate, interface, pointer, etc., one feature of objectization is until the object instantiation Object allocation system resources, that is, the object is flexible, and the optimization assignment of system resources will have positive significance. In some articles, "Lazy Initialization" advocates the instantiation of objects when necessary, in this principle, from the outside of the class, the class can be initialized when it is about to be used; in the interior of the class Elements such as attributes, can also be initialized in the constructor, and until the attribute's getter is truly accessed, if the attribute has not been read, it is not necessary to use the network, database, memory, and Threads and other resources. But not initialization, the better, because initialization is required, and initialization before use can result in a slow response speed of the class, and cannot adapt to the real-time demand for the user. Therefore, it is an instantiated best time to seek a balance between resource occupancy and initial consumption. to sum up

This article surrounds two ways to achieve a collection class - inheriting from CollectionBase inherits and built an ArrayList object, showing some of the collection, indexer, attributes, and characteristics of some collection, and. Other related knowledge such as class constructor, object optimization, class associations in the NET environment. Through the examples and elaborations of this article, I hope that the sense of readers can be inspired, and the basic theory and application models are launched.

Author: Firebird

Redbirdli@hotmail.com

Take a collection class overview .NET Collectes and related technologies via C #

Establish communication and data exchange servers with Delphi - TRANSCEIVER technology (on)

Establish communication and data exchange servers with Delphi - TRANSCEIVER technology (below)

Old Things: Program Shortcut / Program Delete / EXE Self Delete DIY

Old things: childhood programming algorithm

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

New Post(0)