Chapter 5
The previous chapter discusses the data type and their usage. Now we move to C #, which is crucial - class. Without a class, even simple C # programs cannot be compiled. This chapter assumes that you know the basic components of a class: method, attribute, constructor, and destructor. C # has increasing indexes and events.
In this chapter, you learned the topic of the following classes.
. Use constructor and destructor
. Write method
. Give a class increasing attribute access flag
. Realize index
. Create an event and link the customer through representative
. Apply, members, and access modifiers.
5.1 Constructor and destructor
The statement that you can access a class method, attribute, or any other thing, the first executed statement is a constructor containing the corresponding class. Even you don't write a constructor, there will be a default constructor to provide you.
Class testclass
{
Public TestClass (): base () {} // is provided by the compiler
}
A constructor is always the same as its class name, however, it does not declare the return type. In short, the constructor is always public, you can use them to initialize the variable.
Public TestClass ()
{
// This gives a variable here
// Initialization code, etc.
}
If the class contains only static members (can be called by types, instead of instance calls), you can create a private constructor.
Private testclass () {}
Although access to modifiers will be discussed in this chapter, Private means that it is impossible to access the constructor from the outside of the class. So, it cannot be called, and there is no object to be instantiated from this class definition.
Not limited to the parametric constructor - you can pass the initial parameters to initialize the member.
Public TestClass (String Strname, INT NAGE) {...}
As a C / C programmer, you may be accustomed to writing an additional method for initialization because there is no return value in the constructor. Of course, although there is no return value in C #, you can trigger a homemade exception to get the return value from the constructor. More knowledge about exception handling is discussed in Chapter 7 "Abnormal Processing".
However, when you reserve reference to valuable resources, you should think of a way to resolve: A way to be explicitly adjusted to release these resources. The problem is to write an additional method when you can do the same thing in the destructor (named "~" in front of the class name).
Public ~ TestClass ()
{
// Clear
}
The reason you should write an additional method is the garbage collector, which will not be called immediately after the variable is out of range, and only triggered when the intermittent period or memory condition is satisfied. When you lock the resource longer than the time you plan, it will happen. Therefore, providing an explicit release method is a good idea, which can also be called from the destructor.
Public void release ()
{
/ / Release all valuable resources
}
Public ~ TestClass ()
{
Release ();
}
The release method in the call destructor is not necessary - in short, the garbage collection will pay attention to the release of the object. But there is no forgetting to clear is a good habit.
5.2 method
Since the object can initialize and end correctly, the remaining is to increase the function in the category. In most cases, the main part of the function can be achieved in the method. You have already seen the use of static methods, however, these are parts of type (class), not examples (objects).
In order for you to get started quickly, I arranged these cumbersome problems in three:
. Method parameters
. Rewriting method
. Method shield
5.2.1 Method parameters
Due to ways to process change values, you have fewer transfer values to the method, and get the return value from the method. The following three parts relate to problems caused by the transfer value and the returning result of the caller. . Input parameters
. Quote parameter
. Output parameters
5.2.1.1 Enter parameters
One parameter you have seen in the example is the input parameter. You use an input parameter to pass a variable by value to a method - the variable of the method is initialized by a copy of the value passed by the caller. Listing 5.1 Demonstration of input parameters.
Listing 5.1 Transfer parameters by value
1: USING System;
2:
3: Public Class SquareSample
4: {
5: Public Int Calcsquare (int nsideLength)
6: {
7: Return nsideLength * nsideLength;
8: }
9: }
10:
11: Class SquareApp
12: {
13: Public static void main ()
14: {
15: SquareSample SQ = New SquareSample ();
16: console.writeLine (Sq.calcsquare (25) .tostring ());
17:}
18:}
Because I transfer value instead of reference to a variable, a constant expression (25) can be used when the method is called (see Chapter 16). The integer result is transmitted to the caller as the return value, which is displayed immediately on the screen without the intermediate variable.
Enter parameters work in a working mode that C / C programmers have been habits. If you are from VB, please pay attention to the implicit BYVAL or BYREF that can be processed by the compiler, if not set, the parameter always passes.
This seems to have conflicts with me in front: For some variable types, the value transfer actually means that the reference is passed. Confusion? Little background knowledge does not need: COM is the interface, each class can have one or more interfaces. An interface is just a set of function pointers, which does not contain data. Repeating the array will waste a lot of memory resources; so only the start address is copied to the method, which is the same pointer to the interface as the caller. That is why the object uses a value to pass a reference.
5.2.1.2 Quote Parameters
Although many methods can be established with input parameters and return values, you think of it to pass values and modify it in place (that is, in the same memory location), it is not so good. It is very convenient to use the reference parameters here.
Void mymethod (Ref Int Ninout)
Because you pass a variable to this method (not just its value), the variable must be initialized. Otherwise, the compiler will alarm. Listing 5.2 Display how to create a method with a reference parameter.
Listing 5.2 Parameters by reference
1: // Class SquareSample
2: USING SYSTEM;
3:
4: Public Class SquareSample
5: {
6: Public void Calcsquare (Ref Int None4all)
7: {
8: none4all * = none4all;
9: }
10:}
11:
12: Class SquareApp
13: {
14: public static void main ()
15: {
16: SquareSample SQ = New SquareSample ();
17:
18: int nsquardref = 20; // must initialize
19: sq.calcsquare (ref nsquardref);
20: console.writeline (nsquardref.tostring ());
twenty one: }
twenty two: }
As seen, all you have to do is to give the definition and calls. Because variables are passed by reference, you can use it to calculate the results and pass the result. However, in a realistic application, I strongly recommend using two variables, an input parameter, and a reference parameter. 5.2.1.3 Output parameters
The third selection of passing parameters is to set it as an output parameter. As this name is implicit, an output parameter is only used to pass back from the method to one result. Another difference between it and the reference parameters is that the caller does not have to initialize the variable to call the method. This is shown in Listing 5.3.
Listing 5.3 Define an output parameter
1: USING System;
2:
3: Public Class SquareSample
4: {
5: Public void Calcsquare (int nsideLength, out int nsquared)
6: {
7: nsquared = nsideLength * nsideLength;
8: }
9: }
10:
11: Class SquareApp
12: {
13: Public static void main ()
14: {
15: SquareSample SQ = New SquareSample ();
16:
17: int nsquared; // does not have to initialize
18: sq.calcsquare (15, out nsquared);
19: console.writeline (nsquared.toString ());
20:}
twenty one: }
5.2.2 Rewriting method
The important principle of object-oriented design is polymorphism. Don't pay attention to a deep theory, a polymorphism means that when the base class programmer has designed a method for rewriting, in the derived class, you can redefine (rewritten) the method of the base class. Base class programmer can use Virtual keyword design method:
Virtual void canboverridden ()
When derived from the base class, all you have to do is add Override keywords in a new method:
Override void canboverridden ()
When rewriting a basic class method, you must understand that you cannot change the access properties of the method - behind this chapter, you will learn more about accessing the modifier.
In addition to rewriting the basic class method, there is another or more important rewriting feature. When the derived class is forced to convert into a base type and then call the virtual method, the method called the derived class is not a method of the base class.
(Baseclass) DerivedClassInstance) .canboverridden ();
In order to demonstrate the concept of a virtual method, Listing 5.4 shows how to create a triangular base class, which has a member method that can be rewritten (Computerea).
Listing 5.4 Removing a basic class method
1: USING System;
2:
3: Class Triangle
4: {
5: Public Virtual Double ComputeArea (int A, int B, int C)
6: {
7: // Heronian Formula
8: Double S = (A B C) / 2.0;
9: double darea = math.sqrt (s * (s-a) * (s-b) * (s-c));
10: Return Darea;
11:}
12:}
13:
14: Class RightangledTriangle: Triangle
15: {
16: Public Override Double ComputeArea (int A, Int B, INT C)
17: {
18: Double Darea = a * b / 2.0;
19: Return Darea;
20:}
twenty one: }
twenty two:
23: Class TriangletestApp
twenty four: {
25: Public static void main ()
26: {
27: Triangle Tri = New Triangle ();
28: Console.writeline (Tri.ComputeArea (2, 5, 6));
29:
30: RightangledTriangle Rat = new rightangledtriangle ();
31: console.writeline (Rat.comPuteArea (3, 4, 5));
32:}
33:}
The basic class Triangle defines the method computerea. It uses three parameters, returns a Double result and has public access. From the Triangle class, RightangledTriangle, rewritten the ComputeArea method and implemented its own area calculation formula. Both classes are instantiated and verified in the main () method of the application class named TriangleTestApp.
I have leaked the release of Chath:
Class RightangledTriangle: Triangle
The colon (:) in the class statement is represented by RightangLeTRIANGLE from class Triangle. That is what you have to do, so that C # knows you want to treat Triangle as the base class of RightangledTriangle.
When you carefully observe the COMPUTEAREA method of the right angle triangle, you will find that the third parameter is not used to calculate. However, using this parameter can verify that it is "right angle". As shown in Listing 5.5.
Listing 5.5 Calling the base class implementation
1: Class RightangledTriangle: Triangle
2: {
3: Public Override Double ComputeArea (int A, Int B, INT C)
4: {
5: Const Double Depsilon = 0.0001;
6: double darea = 0;
7: IF (Math.abs ((A * A B * B - C * C)> Depsilon)
8: {
9: Darea = Base.computeArea (A, B, C);
10:}
11: Else
12: {
13: DAREA = a * b / 2.0;
14:}
15:
16: RETURN DAREA;
17:}
18:}
This test simply utilizes the Pydalas formula, for the right angle triangle, the detection result must be 0. If the result is not 0, the class calls the COMPUTEAREA of its base class.
Darea = base.computeArea (A, B, C);
The main point of example is: By explicitly use the qualification examination of the base class, you can easily call the base class to implement the rewritable method.
This is very helpful when you need to implement its features in the base class, but don't want to repeat it in the rewrite method.
5.2.3 Method Shield
A different means of the redefine method is the method of shielding the base class. This feature is particularly valuable when derived class from the class provided by others. Look at Listing 5.6, assuming that BaseClass is written by others, and you derive DeriveDclass from it.
Listing 5.6 Derived Class implements a method that is not included in Base Class
1: USING System;
2:
3: Class BaseClass
4: {
5:}
6:
7: Class DerivedClass: Baseclass
8: {
9: public void testmethod () 10: {
11: Console.Writeline ("DeriveDclass :: TestMethod");
12:}
13:}
14:
15: Class TestApp
16: {
17: Public static void main ()
18: {
19: derivedclass test = new derivedclass ();
20: Test.TestMethod ();
twenty one: }
twenty two: }
In this example, DeriveDClass implemented an additional feature through TestMethod (). However, if the developer of the base class believes that the testMethod () is a good idea in the base class, and what is the problem when using the same name to implement it? (See Listing 5.7)
Listing 5.7 Base Class implementation and derived class
1: Class Baseclass
2: {
3: Public void testmethod ()
4: {
5: Console.writeline ("Baseclass :: TestMethod");
6:}
7:}
8:
9: Class DerivedClass: Baseclass
10: {
11: Public void testmethod ()
12: {
13: Console.Writeline ("DeriveDclass :: TestMethod");
14:}
15:}
In an excellent programming language, you will now encounter a real cumbersome. However, C # will give you a warning:
hiding2.cs (13,14): warning CS0114: 'DerivedClass.TestMethod ()' hides inherited member 'BaseClass.TestMethod ()' To make the current method override that implementation, add the override keyword Otherwise add the new keyword...
(Hiding2.cs (13,14): Warning CS0114: 'DeriveDclass.TestMethod ()' Blocks the successful member 'baseclass.testMethod ()'. To enable the current method to overwrite the original implementation, plus Override keywords. Otherwise, add a new keyword.)
With modifier New, you can tell the compiler that you don't have to rewrite the derived class or change the code to use the derived class, your method can block the newly added base class method. Listing 5.8 Display how to use New modifiers in an example.
Listing 5.8 Shielding Base
1: Class Baseclass
2: {
3: Public void testmethod ()
4: {
5: Console.writeline ("Baseclass :: TestMethod");
6:}
7:}
8:
9: Class DerivedClass: Baseclass
10: {
11: New public void testmethod ()
12: {
13: Console.Writeline ("DeriveDclass :: TestMethod");
14:}
15:}
The additional new modifier is used, and the compiler knows that you will redefine the basic class, it should shield the base class method. However, if you are written as follows:
DerivedClass test = new derivedclass ();
(Baseclass) Test .TestMethod ();
The implementation of the base class method is called. This behavior is different from the rewriting method, and the latter guarantees that most derived methods are called.
5.3 class properties
There are two ways to reveal the naming properties of the class - through the domain member or by attribute. The former is implemented as a member variable with public access; the latter does not respond directly to the storage location, just accessible by access logo (Accessors).
When you want to read or write the value of the property, the access flag limits the statement implemented. The access flag for reading the value of the attribute is a keyword GET, and the read and write error flag to modify the value of the property is SET.
Before you know the theory, please take a look at the example in Listing 5.9, the attribute SquareFeet is marked with GET and SET access flags.
Listing 5.9 Implementing attribute access flags
1: USING System;
2:
3: Public Class House
4: {
5: private int m_nsqfeet;
6:
7: Public int squarefeet, PUBLIC INT SQUAREFEET
8: {
9: get {return m_nsqfeet;}
10: set {m_nsqfeet = value;}
11:}
12:}
13:
14: Class TestApp
15: {
16: Public static void main ()
17: {
18: house myhouse = new house ();
19: myhouse.squarefeet = 250;
20: console.writeline (myhouse.squarefee);
twenty one: }
twenty two: }
The House class has a property named SquareFeet that can be read and written. The actual value is stored in a variable that can be accessed from the class - if you want to turn it as a domain member to override it, what you want to do is to ignore the access flag and redefine the variable as:
Public int squarefeet;
For a simple variable, this is not bad. However, if you want to hide the details of the internal storage structure, you should use the access flag. In this case, the SET access flag delivers a new value in the attribute in the value parameter. (You can change your name, see 10th line.)
In addition to hiding the implementation details, you can freely define a variety of operations:
GET and SET: Allow read and write access to attributes.
GET ONLY: Only the value of the read attribute is allowed.
SET ONLY: Only the value of the write attribute is allowed.
In addition, you can get an opportunity to achieve valid code in the set flag. For example, you can reject a new value due to various reasons (or if there is no reason). It is best to tell you that it is a dynamic attribute - when you ask it, it will save it, so you can postpone resource allocation as much as possible.
5.4 index
Do you want to use an index access class like an array? Using the C # index function, it can be knotted.
The syntax is basically like this:
Property modifier declaration {declared content}
Specific example
Public string this [int nindex]
{
Get {...}
Set {...}
}
Index returns or press the INDEX setting string. It doesn't have attributes but uses a public modifier. The declaration part is used by type String and this composition for representation of the index of the class.
Get and set execution rules and properties are the same. (You can't cancel one.) There is only one difference, that is, you can almost arbitrarily define parameters in the burous arc. Restrictions, at least one parameter must be specified, allowing REF and OUT modifiers. This keyword ensures an explanation. Index No user-defined name, this represents the index of the default interface. If the class implements multiple interfaces, you can add more indexes description by InterfaceName.THIS.
To demonstrate an index, I created a small class that can resolve a host name IP address - or an IP address list (take http://www.microsoft.com as an example). This list can be accessed by indexing, you can take a look at the specific implementation of the list 5.10.
Listing 5.10 Get an IP address through an index
1: USING System;
2: USING SYSTEM.NET;
3:
4: Class Resolvedns
5: {
6: ipaddress [] m_arrips;
7:
8: Public void resolve (String strhost)
9: {
10: iphostentry iphe = dns.gethostbyname (strhost);
11: m_arrips = iphe.addresslist;
12:}
13:
14: Public ipaddress this [int nindex]
15: {
16: Get
17: {
18: Return M_Arrips [NINDEX];
19:}
20:}
twenty one:
22: Public Int Count
twenty three: {
24: get {return m_Arrips.Length;
25:}
26:}
27:
28: Class DNSResolVerapp
29: {
30: Public static void main ()
31: {
32: Resolvedns myDnsResolver = new resolvedns ();
33: MyDNSResolver.Resolve ("http://www.microsoft.com");
34:
35: int ncount = myDnsResolver.count;
36: console.writeLine ("Found {0} IP's for hostname", ncount);
37: for (int i = 0; I 38: console.writeline (MyDnsResolver [i]); 39:} 40:} In order to solve the host name, I used the DNS class, which is part of the SYSTEM .NET name space. However, since this name space is not included in the core library, the library must be referenced in the compile command line: CSC /R :system.net.dll /out:resolver.exe dnsreesolve.cs The resolution code is parsed forward. In this resolve method, the code calls the DNS class's static method gethostByname, which returns an iPhostentry object. As a result, the object contains an array that I want to find - ADDRESSLIST. Before exiting the Resolve method, in the local object instance member m_arrips, a copy of the AddressList Array is stored (the object stored in type ipaddress) is stored. With the currently generated array, the application code can raise the IP address in lines 37 to 38 by using the indexes obtained in the class resolvedns. (In Chapter 6, "Control Statement", there are more information about the statement.) Because there is no way to change the IP address, only GET access flags are used only for the index. For simple view, I ignore the boundary overflow check of the array. 5.4 incident When you write a class, sometimes it is necessary to let the class customers know some events already. If you are a programmer with multi-year programming experience, there seems to have a lot of solutions, including function pointers for callbacks and event reception for ActiveX controls. Now you will learn another way to associate customer code to class notifications - use events. The event can be declared as a class member (member variable), or may be declared as attributes. The commonality of the two must be a representative element, while the function pointers and C # represents the same meaning. Each event can be occupied by 0 or more customers, and customers can associate or cancel events at any time. You can define a representative of a representative in a static or instance method, while the latter is very popular with C programmers. Since I have mentioned all the functions of the event and the corresponding representative meta, please see the example in Listing 5.11. It vividly reflects the theory. Listing 5.11 Realizing event processing in the class 1: USING System; 2: 3: // Declaration forward 4: Public Delegate Void EventHandler (String Strtext); 5: 6: Class Eventsource 7: { 8: Public Event EventHandler Textout; 9: 10: Public void triggerevent () 11: { 12: IF (null! = Textout) Textout ("Event Triggered"); 13:} 14:} 15: 16: Class TestApp 17: { 18: Public static void main () 19: { 20: Eventsource evtingrc = new events(); twenty one: 22: evtsrc.textout = new eventhandler (catChevent); 23: Evsrc.triggerevent (); twenty four: 25: evtsrc.textout - = new eventhandler (catChevent); 26: evtsrc.triggerevent (); 27: 28: Testapp theapp = new testApp (); 29: evtsrc.textout = new eventhandler (theapp.instancecatch); 30: evtsrc.triggerevent (); 31:} 32: 33: Public static void catchevent (String Strtext) 34: { 35: console.writeline (strText); 36:} 37: 38: Public void instancecatch (String Strtext) 39: { 40: Console.WriteLine ("Instance" strtext); 41:} 42:} The fourth line declares that representative dollars (origin), which is used to give members a member of the EventSource class declaration of the 8th line. You can observe that the representative is a new type declaration that can be used as a representative element when declaring events. This class has only one way, which allows us to trigger events. Please note that you must conduct event domain members not detection of NULL, as there may be no customer interest in this situation. The TestApp class contains the main method, as well as the other two methods, which have the signals necessary for events. One of the methods is static, and the other is an example method. EventSource is instantiated, and the static method Catchevent is preustomed to the TEXTOUT event: Evsrc.textout = new eventhandler (catChevent); From now on, the method is called when the event is triggered. If you are not interested in the event, simply cancel the association: Evsrc.textout - = New EventHandler (CATCHEVENT); Note that you cannot cancel the associated processing function - only these processing functions are created in class code. In order to prove that the event handler is also working with the instance method, the remaining code establishes the example of TestApp, and hooks the event processing method. Where is the event is particularly useful? You will often involve events and representatives often in ASP or in WFC (Windows Foundation Classes). 5.5 Application modifier During this chapter, you have already seen modifiers like public, virtual. I want to summarize them with an easy-to-understand method, I divide them into three quarters: . Class modifier . Member modifier . Access modifier 5.5.1 class modifier So far, I have not involved in class modifiers, but only involve access modifiers applied to classes. However, there are two modifiers you can use for classes: Abstract - An important point on abstract classes is that it cannot be instantiated. Only not abstract derived classes can be instantiated. Detective classes must implement all abstract members of the abstract base class. You can't use Sealed modifiers to abstract classes. Sealed - the seal cannot be inherited. Use this modifier to prevent accidental inheritance, use this modifier in the .NET frame. To see the use of two modifiers, look at Listing 5.12, which created a sealing class based on an abstract class (definitely a very extreme example). Listing 5.12 Abstract class and seal 1: USING System; 2: 3: Abstract Class AbstractClassClass 4: { 5: Abstract public void mymethod (); 6:} 7: 8: Sealed Class DerivedClass: AbstractClass 9: { 10: public override void mymethod () 11: { 12: console.writeline ("Sealed Class"); 13:} 14:} 15: 16: Public Class TestApp 17: { 18: Public static void main () 19: { 20: DerivedClass DC = New DerivedClass (); 21: dc.mymethod (); twenty two: } twenty three: } 5.5.2 Member modifier Compared with the number of modifications of useful members, there are few quantities. I have mentioned some, this book is about to appear an example of other member modifiers. The following is a useful member modifier: Abstract - Description A method or access flag cannot contain an implementation. They are all implicit virtuals, and in the inheritance class, you must provide Override keywords. Const - This modifier is applied to domain members or local variables. The time-translational constant expression is evaluated, so it cannot contain a reference to the variable. Event - Defines a domain member or attribute as a type event. Events used to bundle customer code to classes. Extern - tells the compiler method to actually be implemented by external implementation. Chapter 10, "And non-accomplished code" will fully involve external code. Override - Methods and access flags used to rewrite any base class are defined as Virtual. The names and base classes to be rewritten must be consistent. READOONLY - A domain member using the Readonly modifier can only be changed in its declaration or in a constructor containing its class. Static - member that is declared as static is a class, not an instance of a class. You can use static to domain members, methods, properties, operators, even constructor. Virtual - Description Method or Access flag can be rewritten by inheritance. 5.5.3 Access modifier Acquisition modifiers define some code to the access level of class members such as methods and properties. You must add a desired access modifier to each member, otherwise the default access type is implied. You can apply 4 access modifiers: Public - anywhere can access the member, which is a minimum restricted access modifier. Protected - You can access the member in class and all derived classes, and external access is not allowed. Private - only within the same class can access the member. Even derived classes cannot access it. INTERNAL - Allows all code access to the same component (application or library). At the .NET component level, you can treat it as public, while the outside is Private. In order to demonstrate the usage of the exemption, I have modified Triangle examples, enabling it a new domain member and a new derive class (see Listing 5.13). Listing 5.13 Using access modifiers in the class 1: USING System; 2: 3: Internal Class Triangle 4: { 5: protected int m_a, m_b, m_c; 6: Public Triangle (int A, int B, INT C) 7: { 8: m_a = a; 9: m_b = b; 10: m_c = C; 11:} 12: 13: Public Virtual Double Area () 14: { 15: // Heronian Formula 16: Double S = (M_A M_B M_C) / 2.0; 17: Double Darea = Math.sqrt (S * (S-M_A) * (S-M_B) * (S-M_C)); 18: RETURN DAREA; 19:} 20:} twenty one: 22: Internal Class Prism: Triangle twenty three: { 24: Private Int M_H; 25: Public Prism (int A, int B, Int C, INT H): Base (A, B, C) 26: { 27: m_h = h; 28:} 29: 30: Public Override Double Area () 31: { 32: Double Darea = Base.area () * 2.0; 33: DAREA = m_a * m_h m_b * m_h m_c * m_h; 34: RETURN DAREA; 35:} 36:} 37: 38: Class PrismApp 39: { 40: public static void main () 41: { 42: Prism Prism = New Prism (2, 5, 6, 1); 43: console.writeline (Prism.area ()); 44:} 45:} Triangle class and PRISM class are now marked in Internal. This means they can only be accessed in the current component. Keep in mind that the term ".NET component" refers to packaging (packaging,) instead of the components you might be used in COM . Triangle classes have three protected members that are initialized in the constructor and are used in the method of area calculation. Since these members are protected members, I can access them in derived PRISM, where different area calculations are performed. Prism has added a member M_H, which is private - or even derived classes cannot access it. It is often a good idea for each class member or even each class. When you need to introduce modifications, a comprehensive plan will eventually help you, because there is no programmer that is willing to use the "No Document" class feature. 5.6 small knot This chapter shows various elements of the class, which is a template for running an instance (object). The code first executed is a constructor in the lifetime of an object. The constructor is used to initialize the variable, which later used in the method to calculate the results. Method allows you to transfer values, reference to variables, or only one output value. Methods can be rewritten to implement new features, or you can block base classes, if it implements the same name with the derived class member. Naming properties can be implemented as domain members (member variables) or attribute access flags. The latter is GET and SET access flags, ignore one or another, you can create only write or read properties. The access flag is well suited to confirm the value assigned to the property. Another feature of the C # class is an index, which is possible to enable the like-by-array syntax. Also, if you happen to some things in the class, you want the customer to get notifications, let them associate with the event. When the garbage collector calls the destructor, the life of the object is over. Since you can't accurately predict this situation, you should create a method to release these valuable resources when you stop using them.