2023/11/7–C#–The difference between generics and Object types, generic constraints, ArrayList variable array, Dictionary dictionary class in C#….

1. Use of generics

Generics is a programming concept that allows you to write code that can handle non-specific data types, thereby improving code reusability and type safety. Generics allow you to write common algorithms, data structures, and methods to adapt to a variety of different data types without having to write specific code for each data type. In C#, generics are primarily implemented through type parameters and generic classes, methods, and interfaces.

Create a generic class with one or more type parameters that allow you to specify a specific data type when instantiating the class. For example:

public class GenericList<T>
{
    private List<T> items = new List<T>();

    public void Add(T item)
    {
        items.Add(item);
    }

    public T Get(int index)
    {
        return items[index];
    }
}

Create generic methods that can operate on different data types. For example:

public T FindMax<T>(T[] array) where T : IComparable
{
    if (array.Length == 0)
        throw new InvalidOperationException("The array is empty.");

    T max = array[0];
    foreach (T item in array)
    {
        if (item.CompareTo(max) > 0)
        {
            max = item;
        }
    }
    return max;
}

Create a generic interface to define methods that can be implemented on different data types. For example:

public interface IRepository<T>
{
    void Add(T item);
    void Delete(T item);
    T GetById(int id);
}

You can use generic constraints to restrict the data types that can be used on a generic method or generic interface. For example, where T : IComparable means that type T must implement the IComparable interface.

public T FindMax<T>(T[] array) where T : IComparable
{
    // ...
}

Generics are very useful in writing generic and type-safe code. By using generics, you can implement common algorithms on different data types without having to rewrite large amounts of similar code. This improves code maintainability and scalability.

2. Use of Object type:

The Object type is a common type in many programming languages and is often used to store objects of any data type. It is a generic type, also known as a universal type, that allows you to handle various types of data when programming. In C#, the Object type is usually called System.Object, while in other programming languages it may have a different name, such as Object > or Any.

(1) Boxing and unboxing: In C#, the process of converting value types (such as integers, floating point numbers) to Object types is called boxing, and converting The process of converting an Object type back to the original value type is called unboxing. This is because the Object type can hold any data type. Example:

int number = 42;
object boxedNumber = number; // boxing
int unboxedNumber = (int)boxedNumber; // Unboxing

Boxing and unboxing can cause performance overhead because they involve conversions of data types.

(2) Use Object for polymorphism: The Object type can be used to implement polymorphism, allowing you to store objects of different types in a variable, and then use it at runtime Different operations are performed based on the actual type of object.

object shape;
shape = new Circle(); // Store Circle object
shape = new Rectangle(); // Store Rectangle object

// At runtime, perform different operations based on the actual type of the object
if (shape is Circle)
{
    Circle circle = (Circle)shape;
    //Perform operations related to Circle
}

(3) Universal data container: The Object type is often used to create a universal data container. For example, different types of data can be stored in an array or collection.

List<object> mixedData = new List<object>();
mixedData.Add(42);
mixedData.Add("Hello, World!");
mixedData.Add(new Circle());

foreach (object item in mixedData)
{
    // Handle various types of data
}

(4) Reflection: The Object type is often used in reflection because it can be used to store the results of reflection operations, such as obtaining the properties, methods and fields of objects.

object obj = Activator.CreateInstance(typeof(MyClass));
PropertyInfo propertyInfo = obj.GetType().GetProperty("SomeProperty");
object propertyValue = propertyInfo.GetValue(obj);

Although the Object type provides a common way to handle different types of data, it also has some limitations. Because type information is lost at compile time, data type conversion and checking need to be handled carefully at run time to avoid potential type errors. Therefore, it is recommended to avoid using the Object type when strong typing is possible to improve type safety.

//Convert value type to reference type. This conversion is called binning. The opposite process is called unboxing
int number = 10;
// boxing
object obj = number;
// unboxing
number = (int)obj;
Object type
> Advantages:
> 1. The object type can be used to reference instances of any type;
> 2. The object type can store any type of value;
> 3. You can define parameters of object type;
> 4. You can use object as the return type.

> Disadvantages:
> 1. An error will occur because the programmer does not remember the type used, resulting in type incompatibility;
> 2. The mutualization of value types and reference types, that is, boxing and unboxing, degrades system performance.

3. Generic constraints

Data constraints in generics can specify the scope of the generic type (generic constraints)

There are five types of generic constraints in total.
Constraint Description
T: Structure type parameters must be value types
T: Class type parameters must be reference types; this also applies to any class, interface, delegate, or array type.
T: new() type parameters must have a parameterless public constructor. When used with other constraints, the new() constraint must be specified last.
T: The type parameter must be the specified base class or derived from the specified base class.
T: The type parameter must be the specified interface or implement the specified interface. Multiple interface constraints can be specified. Constraint interfaces can also be generic.

Example:

 public class People<T,K,V,W,D,X,G> where T : struct //Constraint T must be a value type
                           where K : class //Constraint K must be a reference type
                           where V :IMyInterface //Constraint V must implement the IFace interface
                           where W : K //Constraint W must be of type K, or a subclass of type K
                           where D : MyClass //Constraint D must be of type MyClass, or a subclass of type MyClass
                           where X : class, new() //Constraint X must be a reference type and have a parameterless constructor. When there are multiple constraints, new() must be written at the end
                           where G : class, IMyInterface,new()
 {

     public T value { get; set; }

 }

Generic default value problem requires the default() method

4.ArrayList variable array

Advantages of ArrayList:
The size of ArrayList dynamically expands and contracts according to the data stored in it.
ArrayList does not need to specify its length when declaring the object
ArrayList can easily add, insert and delete data.
ArrayList can store any type
Disadvantages of ArrayList:
ArrayList uses object type when storing data.
ArrayList is not type-safe, and type mismatch errors are likely to occur when using it.
Even if the same type of data is inserted, we still need to convert them into the corresponding original type for processing.
ArrayList storage suffers from boxing and unboxing operations, causing its poor performance

Comparison of List with other arrays:
List is similar to static array (Array class), both are used to store a set of data of the same type.
List is similar to dynamic array (ArrayList) in that the length of elements is not fixed.

  1. Dynamic size: ArrayList can dynamically increase or decrease its size as needed at runtime, so you don’t need to know the size of the array ahead of time. This makes it ideal for working with an indeterminate number of elements.

  2. Generic types: Starting from .NET Framework 2.0, it is recommended to use generic collections (such as List) instead of ArrayList because generics Collections provide better type safety. But if you need to work with older code or the .NET Framework 1.1, ArrayList will still work.

  3. Supports any object type: ArrayList can store any type of object because it is a collection of Object type. This means you can add integers, strings, objects of custom classes, etc., all into the same ArrayList.

    ArrayList list = new ArrayList();
    list.Add(42);
    list.Add("Hello");
    list.Add(new CustomObject());
    

    4. Methods and properties: ArrayList provides a series of methods and properties for adding, deleting, finding and traversing elements. For example, you can use the Add method to add elements, use the Remove method to remove elements, use the Count attribute to get the number of elements, etc.

    ArrayList list = new ArrayList();
    list.Add(42);
    list.Add("Hello");
    int count = list.Count; // Get the number of elements
    list.Remove("Hello"); // Remove elements
    
  4. Performance Note: Because ArrayList stores an Object type, type conversion is required when accessing elements, which may result in performance overhead. If you know the type of elements you want to store, consider using a generic collection such as List to avoid type conversion overhead.

    List<int> numbers = new List<int>(); // Use generic List instead of ArrayList
    numbers.Add(42); // No type conversion required
    
  5. Summary: ArrayList is an old mutable array collection type used to store objects. However, if you are writing new code in a .NET Framework 2.0 or later environment, it is more recommended to use generic collections for better type safety and performance.

5.Dictionary dictionary class

Dictionary is a data structure common in many programming languages that stores key-value pairs. In C#, a Dictionary is a generic collection that stores keys and associated values to enable fast lookup, insertion, and deletion of data. Here is some important information about the Dictionary class in C#:

  1. Generic collection: Dictionary is a generic collection, which means you can specify specific data types for keys and values. For example, you could create a Dictionary where integers are the keys and strings are the values.

  2. Key uniqueness: In a Dictionary, each key must be unique. This means you cannot have duplicate keys in the same dictionary.

  3. Fast lookups: Dictionary uses a hash table data structure to store key-value pairs, which makes it ideal for fast lookups of data. The operation of finding a value for a specific key is usually very efficient, regardless of the size of the dictionary.

  4. Unordered: The key-value pairs in Dictionary are unordered, which means they are not stored in a specific order. If you need to access keys or values in order, you may need to perform additional operations such as sorting.

  5. Methods and Properties: Dictionary provides a set of methods and properties for adding, deleting, finding, and iterating over key-value pairs. Some commonly used methods include Add for adding a key-value pair, Remove for removing a key-value pair, and TryGetValue for trying to get the same The value associated with a specific key, etc.

    Dictionary<int, string> dict = new Dictionary<int, string>();
    dict.Add(1, "One");
    dict.Add(2, "Two");
    string value;
    if (dict.TryGetValue(1, out value))
    {
        Console.WriteLine("Value for key 1: " + value);
    }
    
  6. Initialization: In C#, you can initialize a Dictionary using an object initializer.

    Dictionary<int, string> dict = new Dictionary<int, string>
    {
        { 1, "One" },
        { 2, "Two" },
    };
    

In short, Dictionary is a powerful data structure in C# for storing key-value pairs. It provides efficient lookup operations, as well as rich methods and properties to manipulate data in the dictionary. This makes it a common choice for working with collections of key-value pairs, especially when you need to find and retrieve data quickly.