Introduction: every 10 years or so, programmers need to spend a lot of time and energy learning new programming technologies. In 1980s, it was Unix and C, and in 1990s it was Windows and C ++. Now it has reached Microsoft's. NETFramework and C #. Although new technologies need to be learned, the benefits are far higher than the labor cost. Fortunately, the analysis and design of most projects using C # And. NET have no essential changes in C ++ and Windows. In this article, I will introduce how to make a leap from C ++ to C.
Many articles have already introduced C #'s improvements to C ++, so I will not repeat these questions here. Here, I will focus on the biggest change from C ++ to C #: the change from an unmanageable environment to a manageable environment. In addition, I will make some mistakes that C # programmers can easily make for your reference. In addition, I will explain some new functions that C # can affect programming.
Series of articles: [changes from C ++ to C # Notes (1) (2) (3) (4)]
Attribute usage
To test the attributes, we create a simple class named MyMath, add two functions to it, and then specify the bugfix attribute for it.
[BugFixAttribute (121, "JesseLiberty", "01/03/05")]
[BugFixAttribute (107, "JesseLiberty", "01/04/05 ",
Comment = "Fixedoffbyoneerrors")]
PublicclassMyMath
The data will be stored together with the metadata. The complete source code and its output are as follows:
Custom Attributes
UsingSystem;
// Create custom attributes assigned to Class Members
[AttributeUsage (AttributeTargets. Class,
AllowMultiple = true)]
PublicclassBugFixAttribute: System. Attribute
{
// Location parameter custom property Constructor
PublicBugFixAttribute
(IntbugID,
Stringprogrammer,
Stringdate)
{
This. bugID = bugID;
This. programmer = programmer;
This. date = date;
}
PublicintBugID
{
Get
{
ReturnbugID;
}
}
// Attributes of the named Parameter
PublicstringComment
{
Get
{
Returncomment;
}
Set
{
Comment = value; publicstringDate
{
Get
{
Returndate;
}
}
PublicstringProgrammer
{
Get
{
Returnprogrammer;
}
}
// Private member data
PrivateintbugID;
Privatestringcomment;
Privatestringdate;
Privatestringprogrammer;
}
// Assign attributes to the class
[BugFixAttribute (121, "JesseLiberty", "01/03/05")]
[BugFixAttribute (107, "JesseLiberty", "01/04/05 ",
Comment = "Fixedoffbyoneerrors")]
PublicclassMyMath
{
PublicdoubleDoFunc1 (doubleparam1)
{
Returnparam1 + DoFunc2 (param1 );
}
PublicdoubleDoFunc2 (doubleparam1)
{
Returnparam1/3;
}
}
PublicclassTester
{
PublicstaticvoidMain ()
{
MyMathmm = newMyMath ();
Console. WriteLine
}
}
Output:
CallingDoFunc (7). Result: 9.3333333333333339
As we can see, attributes have no impact on the output, and creating attributes does not affect the code performance. So far, readers have only listened to my discussion about attributes. When using ILDASM to browse metadata, they will find that attributes exist.
Ing
In many cases, we need a method to access attributes from metadata. C # provides support for ing to access metadata. By initializing an object of the MemberInfo type, the object in the System. Reflection namespace can be used to discover member attributes and access metadata.
System. Reflection. MemberInfoinf = typeof (MyMath );
Call the typeof operator for the MyMath Type. It returns a Type variable generated by inheriting MemberInfo.
The next step is to call GetCustomAttributes for the MemberInfo object and pass the expected attribute type as a parameter to GetCustomAttributes. We will get an array of objects. The type of each member in the array is BugFixAttribute.
Object [] attributes;
Attributes = Attribute. GetCustomAttributes (inf, typeof (BugFixAttribute ));
We can traverse this array and print the array of the BugFixAttribute object, as shown in the Code:
Print attributes
PublicstaticvoidMain ()
{
MyMathmm = newMyMath ();
Console. WriteLine ("CallingDoFunc (7). Result: {0 }",
Mm. DoFunc1 (7 ));
// Obtain the member information and use it to access Custom Attributes
System. Reflection. MemberInfoinf = typeof (MyMath );
Object [] attributes;
Attributes =
Attribute. GetCustomAttributes (inf, typeof (BugFixAttribute ));
// Traverse all attributes
Foreach (Objectattributeinattributes)
{
BugFixAttributebfa = (BugFixAttribute) attribute;
Console. WriteLine ("BugID: {0}", bfa. BugID );
Console. WriteLine ("Programmer: {0}", bfa. Programmer );
Console. WriteLine ("Date: {0}", bfa. Date );
Console. WriteLine ("Comment: {0}", bfa. Comment );
}
}
Type discovery
We can use the image method to study the content of a composite object. This method is very useful if you want to create a tool that needs to display internal information of the composite body or call the path in the composite body dynamically.
Through the image method, we can know the type of a module, method, domain, and attribute, as well as the signal of each method of this type, the interface supported by this class, and the super class of this class. We can use the Assembly. Load Static Method to dynamically Load a combination body in the following form:
PublicstaticAssembly. Load (AssemblyName)
Then, it can be passed to the core library.
Assemblya = Assembly. Load ("Mscorlib. dll ");
Once the combination body is loaded, we can call GetTypes to return an array of Type objects. A Type object is the core of ing. It represents the Type Definitions of classes, interfaces, arrays, values, and enumeration.
Type [] types = a. GetTypes ();
The combination recess returns an array of types. We can use the foreach-loop structure to display this array, and its output will contain several pages of documents. Below we will find a small segment:
TypeisSystem. TypeCode
TypeisSystem. Security. Util. StringExpressionSet
TypeisSystem. Text. UTF7Encoding $ Encoder
TypeisSystem. ArgIterator
TypeisSystem. Runtime. Remoting. JITLookupTable
1205 typesfound
We get an array whose content is of the core library type. We can print them out and the array will have 1205 items.
For a type ing, we can also map one type in the combination. Therefore, we can use the GetType method to parse a type from the combination body:
PublicclassTester
{
PublicstaticvoidMain ()
{
// Check an object
TypetheType = Type. GetType ("System. Reflection. Assembly ");
Console. WriteLine ("SingleTypeis {0}", theType );
}
}
The output is as follows:
SingleTypeisSystem. Reflection. Assembly
Member discovery
We can also get the types of all members and display all methods, attributes, and domains. The following Code demonstrates the code to achieve the above objectives.
Figure9GettingAllMembers
PublicclassTester
{
PublicstaticvoidMain ()
{
// Check a single object
TypetheType = Type. GetType ("System. Reflection. Assembly ");
Console. WriteLine ("SingleTypeis {0}", theType );
// Obtain all members
MemberInfo [] mbrInfoArray =
TheType. GetMembers (BindingFlags. LookupAll );
Foreach (MemberInfombrInfoinmbrInfoArray)
{
Console. WriteLine ("{0} isa {1 }",
MbrInfo, mbrInfo. MemberType. Format ());
}
}
}
Although the output is still very long, in the output, we can obtain the following fields, methods, constructors, and attributes that are unwilling to lag behind:
System. Strings_localFilePrefixisaField
BooleanIsDefined (System. Type) isaMethod
Void. ctor () isaConstructor
System. StringCodeBaseisaProperty
System. StringCopiedCodeBaseisaProperty