In the program, it is unavoidable to access the private members of an object. So there are two ways to implement this kind of function, the first method is the simplest one is to change the member accessor from "private" to "public", and the other is to provide access to the member access function. Now, in C # writing a program, you no longer need to use the previous two methods, and directly use the property 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.
So what is the difference between the three methods, using the following table, can better explain the difference between the three.
As a result, it can be seen that the use of attributes does not compromise the encapsulation of the class, does not weaken the security of the Code, and is as simple as the first method, only slightly less efficient than the first method. In general, however, it is not a choice to access the private members of a class in C # using properties.
However, for the use of attributes, and as mentioned in the above table, there will inevitably be some of the following questions.
Question one: is the use of attributes can achieve the same effect as member functions, that is, the completion of 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, you can write as a member function, that is, in the member function can write code snippets, can be applied in the properties. The Microsoft intermediate Language (MSIL) code 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 Property 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 (although the specific implementation code of the function is omitted, because this is not to study the intermediate language code, if you need to know more about this part, see intermediate language related books).
Question two: is the efficiency of using attributes second only to the first method.
It is easy to see from the above that the property will be compiled with the same code as the Sing Woo member function, so its efficiency should be the same as the member function. This is not the case, because the JIT compiler will convert the properties of the two member functions as inline functions, so the efficiency will be much higher. (Note: Inline functions are functions that code is inserted into the caller's code to improve execution efficiency by avoiding the extra overhead of function calls.) However, it is also mentioned in the book that, even if it is not an inline function, the efficiency loss of the member function relative to method one is negligible. )
Write the program in C #, a reference to the property, everyone will write. In fact, in the attribute, can produce a lot of applications, followed by the separate description.
!--[If!supportlists]-->1. The!--[endif]--> uses an index character in a property, such as "arraylist[i]" to access a member of ArrayList. It is important to note that the encoding format of the property name and index parameter is fixed, such as "this [...]". However, the index parameter can be multiple, and not only the integer parameter, but also other types of parameters can be used. For example:
Public Returnvaluetype this[ParType1 parValue1, ParType2 parValue2]
{
Get{...}
Set{...}
}
!--[If!supportlists]-->2. The!--[endif]--> can add a mutex to a property operation to prevent concurrency errors that sometimes occur during 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 properties and non-read-only properties in a class. But I personally think that, although this can be achieved, but there will be ambiguity, that is, in a class to provide two different versions of the properties, breaking the class consistency, so I do not recommend this.
Then, to say something about writing properties, I personally think that there are two big points.
The first is to write the Property Get section, if the current property type is a reference type, and do not want to modify the local members through the property, it is best to return the copy of the local member, rather than the member itself.
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 write as above, the Class2 object can access and modify some values of the local member MyClass1 through the Class1.data property, so that the value of the myClass1 of the private member of the MYCLASS2 can be modified, resulting in a potential error.
For example:
Class1 myClass1 = Myclass2.class1;
Myclass1.data = "Test2";
How to avoid such errors, then the first need to modify the Class1 property of the writing, followed by the Class1 class need to provide the clone function or other copy function, 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 validity. Because a property is a portal to a private member of a class that is modified by the outside world, in order to avoid errors caused by a private member being incorrect, a validation check is performed on the property set to ensure that the private member is valid for the entire class.
So in practical application, it is closely related to attribute to realize data access between two forms, which is probably the most basic of writing WinForm program. Unfortunately, when answering such questions online, many people suggest the first way to solve them.
C # Proverbs Use properties to access private members of a class