When we do not define complex methods, events, constructors such as complex classes, you can dynamically generate a custom data type--anonymous type.
1. Defining Anonymous Types
When you define an anonymous type, you need to use the var keyword and object initialization syntax.
var: the compiler automatically generates a new class definition at compile time (we cannot see the name of the class in C # code).
Initialize: It tells the compiler to create a private background field and (read-only) property for the newly created type.
Build an anonymous type by passing parameters and print the relevant information
Private Static voidBiuldanonymoustype (stringMakestringColorintCURRSP) { //building anonymous types with incoming parameters varCar =New{make = make, color = color, CURRSP =CURRSP}; //Get Property DataConsole.WriteLine ($"{car. {Car for Color}. Make} speed {car. CURRSP}"); //An anonymous type contains a custom implementation of each virtual method (virtual) in System.ObjectConsole.WriteLine ($"Tostring={car. ToString ()}");}
Invoke: You can also use hard-coded to build anonymous types
Public Static voidShow () {Console.WriteLine ("Fun with anonymous types"); //Note Anonymous types can also be created by using hard-coded//build an anonymous object to represent the car varCar =New{make ="Honda", Color ="Blue", CURRSP = the }; //output color and carConsole.WriteLine ($"my car is {car. Color}{car. Make}"); //calling a helper method to create an anonymous type from a parameterBiuldanonymoustype ("Baoma"," White", -);}
2. Internal representations of anonymous types
All anonymous types automatically inherit object, so we can tostring,gethashcode,equals on the car object, and we try to call it:
Private Static voidReflectoveranonymoustype (Objectobj) {Console.WriteLine ($"Object instance: {obj. GetType (). Name}"); Console.WriteLine ($"type: {obj. GetType (). Name} base class: {obj. GetType (). BaseType}"); Console.WriteLine ($"toString (): {obj. ToString ()}"); Console.WriteLine ($"GetHashCode (): {obj. GetHashCode ()}");}
Calls and results:
Public Static void Show () { Console.WriteLine ("fun withanonymous types"); // build an anonymous object to represent the car var New " Honda " " Blue " the }; Reflectoveranonymoustype (car);}
The type of car object is: <>f__anonymoustype0 ' 3 (you may be different), anonymous type name is determined by the compiler, we cannot interfere with CIL code.
3. How to implement ToString () and GetHashCode ()
1.ToString ()
Public Override stringToString () {StringBuilder builder=NewStringBuilder (); Builder. Append ("{Color ="); Builder. Append ( This.<color>I_field); Builder. Append (", make ="); Builder. Append ( This.<make>I_field); Builder. Append (", CURRSP ="); Builder. Append ( This.<currsp>I_field); Builder. Append ("}"); returnBuilder. ToString ();}
2.GetHashCode ()
It computes the hash value as the type input of the system.collections.generic.equalitycomparer<t> using a variable of each anonymous type, only if two anonymous types have the same attribute and are given the same value. will produce the same hash value.
4. Equality semantics for anonymous types
Equals ()
Private Static voidequalitytest () {//build two anonymous types with the same name/value pairs varOnecar =New{make ="Honda", Color ="Blue", CURRSP = the }; varTwocar =New{make ="Honda", Color ="Blue", CURRSP = the }; //call equals if(Onecar.equals (Twocar)) {Console.WriteLine ("Equals "Same Anonymous object"); } Else{Console.WriteLine ("Equals "is not the same anonymous object"); } //using the = = operator if(Onecar = =Twocar) {Console.WriteLine ("= = "Same Anonymous object"); } Else{Console.WriteLine ("= = "Not the same anonymous object"); } //Comparing Object Types if(Onecar.gettype (). Name = =Twocar.gettype (). Name) {Console.WriteLine ("same Type"); } Else{Console.WriteLine ("Different Types"); } reflectoveranonymoustype (Onecar); Reflectoveranonymoustype (Twocar);}
Analyze the results:
1.Equals (): Compiler overrides Equals () uses a value based on merit semantics (e.g., values for each data member of two objects) when judging the equality of an object
2.== operator: Because an anonymous type does not have an overloaded equality operator (==,!=), = = compares the reference, not the content.
3.GetType (): Because if we declare two identical (same) anonymous types in the same assembly, the compiler will only generate a definition of an anonymous type.
5. Anonymous types that contain anonymous types
var New { new"Honda""Blue"180 }, 200000}; Reflectoveranonymoustype (order);
Summarize:
In fact, we should be cautious about using anonymous types, especially when using LINQ, never discard strongly typed classes or structs because of the presence of anonymous types.
In fact, the anonymous type itself has many limitations:
- You don't control the name of an anonymous type.
- Anonymous type Inheritance System.Object
- Fields and properties of anonymous types are always read-only
- Anonymous types do not support events, custom methods, custom operators, and custom overrides
- Anonymous types are implicitly closed (implicit sealed)
- Entity creation for anonymous types uses only the default constructor
If we need to quickly define the shape of an entity without having to define its functionality, you can use anonymous types.
Learning, hope you crossing a lot of advice.
C # Anonymous type (Anonymous type) Learning Diary