C# study notes–advanced knowledge points such as data structures, generics, delegate events, etc.
This blog is an advanced part of the C# study notes. It designs advanced knowledge in the C# language and introduces data structures such as List and ArrayList, Stack and Queue, and Hashtable.
Generics, generic type data structures, and the tangled web of delegates and events. It also involves some uncommon but commonly used knowledge points, such as anonymous functions, Lambda expressions, covariance and contravariance, multi-threading,
Knowledge points such as reflection and characteristics. Practice quietly and learn with me!
C# Advanced
Simple data structure class
ArrayList
The element type is stored in the Object type and is an array container that supports addition, deletion, and modification.
Therefore, there are packing and unboxing operations, so use them with caution.
//ArrayList
ArrayList array=new ArrayList();
//Add =================
array.Add("Hello");
array.Add(true);
array.Add("Tony");//Add a single element
array.Add("Hello");
array.Add("World");
ArrayList array2=new ArrayList();
array2.Add("123");
array.AddRange(array2);//Add elements from the array
//insert
array.Insert(1,"456");
//Delete==================
array.Remove("Hello");
array.RemoveAt(1);//Remove elements based on index
array.Clear();//Clear
//Check=================
array[0];
//Check whether the element is stored in
if(array.Contains(true))
{
}
//Forward search for an element
//Return to index. If not found, return -1.
array.IndexOf("Hello");
//Reverse search element position
array.LastIndexOf("Hello");
//Change =======================
array[2]="123";
//Traverse======
//Distinguish between length (used capacity) and capacity
//capacity
array.Capacity;
for(int i=0;i<array.Count;i++)
{
Console.WriteLine(array[i]);
}
//Iterator traverse
foreach(object obj in array)
{
Console.WriteLine(item);
}
//packing and unboxing
What is the difference between ArrayList and array?
- There is no need to specify a fixed length when using ArrayList, but it is required for arrays
- The array stores the specified type, and ArrayList is Object
- Boxing and unboxing of ArrayList exists, but the array does not exist
- The length of the ArrayList array is obtained by Count, and the length of the array is Length
- Add and delete methods are provided in ArrayList, which is easy to use. The array needs to be implemented by yourself
Stack
The essence of stack: it is also an Object array
//Stack first in, last out
//statement
Stack stack=new Stack();
//========Increase===Push onto the stack
stack.Push(1);
stack.Push("23");
stack.Push("Tony");
stack.Push(66.6);
//========Get====Pop the stack
object o=stack.Pop();
//======Check
//The stack can only view the content at the top of the stack. Without an indexer, it cannot be viewed based on the index.
Object look=stack.Peek();
//Check whether there is content in the element
if(stack.Contains("Tony"))
{
Console.WriteLine("This element exists!");
}
//clear
stack.Clear();
//Traverse
foreach(object item in stack)
{
Console.WriteLine(item);
//Get the element from the top of the stack
}
//Convert stack to array
object[] stackArray=stack.ToArray();
//The top element of the stack is in the front part of the array
//loop stack
while(stack.Count>0)
{
object obj=stack.Pop();
Console.WriteLine(obj);
}
//There is boxing and unboxing
Queue
Essence: It is also an object array
//queue first-in-first-out
//statement
Queue queue=new Queue();
//increase
queue.Enqueue(1);
queue.Enqueue(3.15f);
queue.Enqueue("Tony");
//Pick
queue.Dequeue();
//check
queue.Peek();
if(queue.Contains(3.15f))
{
//Print
}
//Change can only be cleared
queue.Clear();
//Traverse
queue.Count();
foreach(object item in queue)
{
Console.WriteLine(item);
}
//Convert to array
object[] objs=queue.ToArray();
for(int i=0;i0)
{
object obj=queue.Dequeue();
Console.WriteLine(obj);
}
Hashtable
Essence: Storage is also stored as object. Hash table, key-value pairs organized based on hash code
The access efficiency can be O(1)
//HashTable
//statement
Hashtable hashtable=new Hashtable();
//Add keys cannot be repeated
hashtable.Add(1,"123");
hashtable.Add("name","TonyChang");
hashtable.Add(3,21);
//Delete --can only be deleted by key
hashtable.Remove(1);
hashtable.Remove("name");
//clear
hashtable.Clear();
//Check if not found it is empty
hashtable[1];
hashtable["name"];
//Verify if it exists
if(hashtable.Contains("name"))
{
//Search based on key
}
if(hashtable.ContainsKey("name"))
{
//Search based on key
}
if(hashtable.ContainsValue("TonyChang"))
{
//Find based on value
}
//You can only find the value through the key, not vice versa
//Traverse
hashtable.Count;//Number of key-value pairs
//Not necessarily printed in insertion order
//Elements are unordered
foreach(object item in hashtable.Keys)
{
Console.WriteLine("key"+item);
Console.WriteLine("value"+hashtable[item]);
}
//Iterate through values
foreach(object item in hashtable.Values)
{
Console.WriteLine("value"+item);
}
//Traverse key-value pairs
foreach(DictionaryEntry item in hashtable)
{Interface
//GetInterfaces
//Get attributes
//GetProperty
//GetPropertys
//================Activator=====
//You can use it to quickly instantiate Type objects
Type testType=typeof(Test);
Test testObj=Activator.CreateInstance(testType) as Test;//No parameter construction
testObj=Activator.CreateInstance(testType,99) as Test;//Construction with parameters
testObj=Activator.CreateInstance(testType,99,"Tony") as Test;//Construction with parameters (parameter types must correspond)
//==============Assembly (assembly class)================
// Mainly used to load other assemblies. After loading, use Type to use its content.
//You can load dll files, etc.
//Three functions for loading assembly
//Generally used to load other assemblies under the same file
Assembly asembly2 = Assembly.Load("assembly name");
//Generally used to load other assemblies that are not under the same file
Assembly assembly = Assembly.LoadFrom("The name or path of the file containing the assembly manifest");
Assembly asembly3 = Assembly.LoadFile("Fully qualified path to the file to be loaded");
//1. First load a specified assembly
Assembly asembly = Assembly.LoadFrom(@"C:\Users\MECHREVO\Desktop\CSharp");
Type[] types = assembly.GetTypes();
//Traverse and print
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i]);
}
//2. Reflection can only be used after loading a class object in the assembly
Type icon = asembly.GetType("Lesson18_Exercise questions.Icon");
MemberInfo[] members = icon.GetMembers();
for (int i = 0; i < members.Length; i++)
{
Console.WriteLine(members[i]);
}
//Instantiate an icon object through reflection
//First get the enumeration Type to get the parameters that can be passed in
Type moveDir = assembly.GetType("Lesson18_Exercise questions.E_MoveDir");
FieldInfo right = moveDir.GetField("Right");
//instantiate the object directly
object iconObj = Activator.CreateInstance(icon, 10, 5, right.GetValue(null));
//Get the method in the object through reflection
MethodInfo move = icon.GetMethod("Move");
MethodInfo draw = icon.GetMethod("Draw");
MethodInfo clear = icon.GetMethod("Clear");
//Call the program
Console.Clear();
while(true)
{
Thread.Sleep(1000);
clear.Invoke(iconObj, null);
move.Invoke(iconObj, null);
draw.Invoke(iconObj, null);
}
//Note: The called program is an exercise in drawing squares
property
Essentially, it is a class that can explain and describe metadata, and can be used to obtain the information of the called metadata during reflection acquisition.
System-generated features:
Obsolete features:
Iterator
Iterator iterator
Sometimes also called cursor, it is a software design pattern. The iterator pattern provides a method to sequentially access the various elements in an aggregate object without exposing its internal identity.
Only classes that implement iterators can use foreach traversal.
//Iterator
//Inherit two interface implementations
//cursor movement
//Iterator
class MyList:IEnumerable,IEnumerator
{
private int[] list;
private int position = -1;
publicMyList()
{
list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
}
//Implement the interface method of IEnumerable
public IEnumerator GetEnumerator()
{
Reset();//Return the index to 0 before returning
return this;
}
//==========================
public object Current
{
get => list[position];
}
//Move the cursor
public bool MoveNext()
{
++position;
return position < list.Length;
}
//reset cursor
public void Reset()
{
position = -1;
}
}
//Traverse! ! In Main method
MyList list = new MyList();
foreach(int item in list)
{
Console.WriteLine(item);
}
Try to understand the nature of foreach:
- First obtain the IEnumerator of the object to be traversed, and call the GetEnumerator method to obtain it
- Execute the MoveNext method in the IEnumerator object
- If the return value is true, continue to call Current to get the value and give it to item
Use syntactic sugar to implement iterators
//Iterator
class MyList1:IEnumerable
{
private int[] list;
publicMyList1()
{
list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
}
//Implement the interface method of IEnumerable
public IEnumerator GetEnumerator()
{
for(int i=0;i<list.Length;i++)
{
//Use syntactic sugar
//yield return is the syntactic sugar provided to us by C#
//The so-called syntactic sugar, also known as sugar-coated syntax
//The main function is to simplify complex logic and increase the readability of the program.
//Thus reducing the chance of program code errors
//To retain the current state, return temporarily
yield return list[i];
//The other two related functions are automatically generated by the system
}
}
//==========================
}
//Traverse! ! In Main method
MyList1 list1 = new MyList1();
foreach(int item in list1)
{
Console.WriteLine(item);
}
Use syntactic sugar to implement iterators for generic arrays
//Generic implementation of iterator class
class MyList : IEnumerable
{
private T[] array;
public MyList(params T[] array)
{
this.array = array;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < array.Length; i++)
{
yield return array[i];
}
}
}
> : IEnumerable
{
private T[] array;
public MyList(params T[] array)
{
this.array = array;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < array.Length; i++)
{
yield return array[i];
}
}
}