Visit | visiting
In a program, it is unavoidable to access the private members of an object. There are two ways to implement this type of functionality before, the simplest of which is to change the member accessors from "private" to "public", and the other is to provide publicly accessible member access functions. So now write a program in C #, you no longer need to take the two methods mentioned above, and directly using the attributes to complete.
First, let's look at how the three methods are implemented and invoked, and here is an example of accessing the private member strname of the "EmployeeInfo" class, as shown in the following table.
|
private string StrName; |
Access method |
To modify a member access character |
Modify: private string StrName; For: public string StrName; |
EmployeeInfo empnew ...; string strnamevalue = Empnew.strname; Empnew.strname = "Me"; |
Public member functions |
Add the following two member functions: public string GetName () { return strName; }
public void SetName (string Name) { StrName = Name; } |
EmployeeInfo empnew ...;
String strnamevalue = Empnew.getname ();
Empnew.setname ("Me"); |
Property |
Add the following properties: public string Name { get{return strName;} set{strName = value;} }
|
EmployeeInfo empnew ...; string strnamevalue = Empnew.name; Empnew.name = "Me"; |
So what is the difference between these three methods, the following table, can better illustrate the difference between the three.
|
Encapsulation of a class |
Code security |
Code complexity |
Code efficiency |
To modify a member access character |
The encapsulation of a broken class |
There is a potential danger |
Simple |
Highest |
Public member functions |
No damage. |
Safety |
Tedious, and the call was not directly |
Minimum |
Property |
No damage. |
Safety |
Simple |
Second only to the first method |
(Note: This indicates the worst of each subkey in red)
Therefore, you can see that using attributes does not destroy the encapsulation of the class, does not weaken the security of the Code, and is as simple as the first method, but slightly less efficient than the first method. But generally speaking, using attributes in C # to access the private members of a class is not the second choice.
However, for the use of attributes and as mentioned in the table above, some questions are inevitably raised.
question one: is the use of attributes to achieve the effect of member functions, that is, complete complex code operations.
In fact, the underlying implementation of the property is the use of member functions, but this part of the conversion is done by the system, so when writing properties, as a member function, that is, in the member function can write code snippets, can be applied in the attribute. The Microsoft intermediate Language (MSIL) code that is converted by the attribute is posted below.
. property instance String Name ()
{
. Get instance string Namespace.employeeinfo::get_name ()
. Set instance void Namespace.employeeinfo::set_name (String)
}//End of Employeeinfo::name
. method public Hidebysig SpecialName instance string get_name () cil managed
{
...
}//End of Method Employeeinfo::get_name
. method public Hidebysig specialname instance void Set_name (string ' value ') CIL managed
{
...
}//End of Method Employeeinfo::set_name
As above is the intermediate language code converted by the Name property of the previous EmployeeInfo class (but omitting the specific implementation code of the function, since this is not intended to be a study of intermediate language code, if you need to know more about this part, refer to the intermediate language books).
question two: is the use of attribute efficiency is second only to the first method.
It's easy to see from the above that when the attribute is compiled, it converts the same code as the Sing Woo member function, and its efficiency should be the same as that of the member function. This is not the case, because the JIT compiler takes the two member functions that the property converts into an inline function, which can be much more efficient. (Note: An inline function is a function that the code is inserted into the caller's code to improve execution efficiency by avoiding the extra overhead of a function call. However, the book also mentions that even if it is not an inline function, the efficiency loss of the member function relative to the method one is negligible. )
Write a program in C #, a reference to attributes, everyone will write. In fact, in the attribute, can produce a lot of applications, and then to explain separately.
!--[If!supportlists]-->1. !--[endif]--> uses an index character in a property, such as "arraylist[i]" to access a ArrayList member. Note that the property name and the encoding format of the index parameter are fixed, such as "this [...]". However, index parameters can be multiple, and other type parameters can be used, not only for integer parameters. For example:
Public Returnvaluetype this[ParType1 parValue1, ParType2 parValue2]
{
Get{...}
Set{...}
}
!--[If!supportlists]-->2. !--[endif]--> can add a mutex to a property operation to prevent concurrent errors from being generated by multithreaded operations, as follows.
public string Name
{
Get
{
Lock (This)
{
return strName;
}
}
Set
{
Lock (This)
{
StrName = value;
}
}
}
!--[If!supportlists]-->3. The!--[endif]--> also mentions other applications of attributes, such as the use of interfaces to provide both read-only and not-read-only properties in a class. But I personally think that, although this can be achieved, but there is ambiguity, that is, in a class to provide two different versions of the properties, breaking the consistency of the class, so I do not recommend this.
Then, to talk about writing attributes, what to pay attention to, I personally think there are the following two points of the big.
The first is to write the property Get part, if the type of the current property is a reference type, and do not want to modify the local members through the attribute, it is best to return the local member copy, rather than the members themselves.
For example:
public class Class1
{
String _data;
public Class1 (String data)
{
_data = data;
}
public string Data
{
get{return _data;}
set{_data = value;}
}
}
public class Class2
{
private Class1 myClass1 = null;
public Class1 Class1
{
get{return MYCLASS1;}
}
public string Data
{
get{return myclass1.data;}
}
Public Class2 (String data)
{
MyClass1 = new Class1 (data);
}
}
If you follow the example above, the Class2 object can access and modify some values of the local members MyClass1 through the Class1.data property, so that you can modify the values of the MyClass2 private member MyClass1, resulting in potential errors.
For example:
Class1 myClass1 = Myclass2.class1;
Myclass1.data = "Test2";
How to avoid such errors, you first need to modify the writing of the Class1 property, followed by the Class1 class need to provide a clone function or other copy functions, as follows:
public class Class1:icloneable
{
String _data;
public Class1 (String data)
{
_data = data;
}
public string Data
{
get{return _data;}
set{_data = value;}
}
#region ICloneable Members
public Object Clone ()
{
Todo:add Class1. Clone implementation
return new Class1 (_data);
}
#endregion
}
public class Class2
{
private Class1 myClass1 = null;
public Class1 Class1
{
get{return Myclass1.clone () as Class1;}
}
public string Data
{
get{return myclass1.data;}
}
Public Class2 (String data)
{
MyClass1 = new Class1 (data);
}
}
The second note is that when you write the property set section, you need to check the parameters for validation. Because the attribute is the entry point of the private member of the external modification class, in order to avoid errors due to improper private members, a validation check is performed on the property set to ensure that the private member is valid for the entire class.
So in the practical application, and the property is closely related to the realization of data access between the two forms, which may be the most basic writing WinForm program. Unfortunately, when answering such questions on the Internet, many people suggested that the first method should be used to solve the problem.