An in depth analysis of c generic type parameters and constraints

  • 2020-05-12 03:09:28
  • OfStack

Introduction to generic type parameters
Generic type parameters are commonly used when defining generic types and generic methods, and generic type parameters are placeholders that specify the type when the generic is instantiated. Generic type parameters are placed in" < > "Within.
Suggestions for generic type parameter naming:
(1) when the generic type parameter is a single letter, it is recommended to use T.
(2) when the generic type parameter is defined by a word, it is recommended to add T before the word.

private void PromptName<T>(T t) {}
private void PromptName<Tuser>(Tuser user){}

Generic type parameter constraints
When defining a generic class, you can impose restrictions on the type types used for type parameters when instantiating a generic class. If you instantiate a generic class with a type that is not allowed by the constraint, a compile-time error occurs.
Generic constraint classification:

The constraint

instructions

T: structure

The type parameter must be a value type. You can specify any value type other than Nullable.

T: class

The type parameter must be a reference type; This point applies to any class, interface, delegate, or array type.

T: new ()

A type parameter must have a public constructor with no arguments. When used with other constraints 1, the new() constraint must be specified last.

T: < The base class name >

The type parameter must be the specified base class or derived from the specified base class.

T: < The name of the interface >

The type parameter must be the specified interface or the implementation of the specified interface. You can specify multiple interface constraints. A constraint interface can also be generic.

T: U

The type parameters provided for T must be those provided for U or derived from those provided for U.


(1) the type parameter constraint is structure (struct).

public class ShowObjectType<T> where T : struct
    {
        public void ShowValue<T>(T t)
        {
            Console.WriteLine(t.GetType());
        }
    }
    class GenericConstraint
    {
        static void Main()
        {

            ShowObjectType<int> showInt = new ShowObjectType<int>();
            showInt.ShowValue<int>(5);
            showInt.ShowValue(5);// Type parameter types can be derived from parameters, and type parameter types can be omitted 

            // Because the constraint is a value type, the following code cannot be compiled 
            ShowObjectType<string> showString = new ShowObjectType<string>();
            showString.ShowValue("5");
            Console.Read();
        }
    }

(2) the type parameter constraint is class (class).
When applying the where T: class constraint, avoid using == and! For type parameters = operator, because these operators only test the type as a reference type, not value equality.

class GenericConstraint
    {
        static void Main()
        {
              List<string > list = new List<string>();
            AddClass<string>(list, "hello generic");
            Console.Read();
        }
        private static void AddClass<T>(List<T> list, T t) where T : class
        {
            list.Add(t);
        }
    }

(3) the type parameter constraint is a concrete class.
When the constraint is a concrete class, the properties and methods of the concrete class can be invoked using the type parameter.

class GenericConstraint
    {
        static void Main()
        {
            Person person = new Person { ID = 1, Name = "David" };
            PromptName<Person>(person);
            Console.Read();
        }
        // This constraint T for Person Object or inheritance Person object 
        private static void PromptName<T>(T t) where T : Person 
        {
            // Available here Person the Name attribute 
            if (t.Name == "David")
            {
                Console.WriteLine("Person name is David");
            }
            string name = t.GetName();
            Console.WriteLine("Person name is {0}", name);
        }
    }
    public class Person
    {
        private int id;
        public int ID
        {
            get { return id; }
            set { id = value; }
        }
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string GetName()
        {
            return Name;
        }
    }

(4) constrain multiple parameters.

class Base { }
class Test<T, U>
    where U : struct
    where T : Base, new() { }

(5) unbound type parameter.
Type parameters without constraints are called unbound type parameters.

class  List<T>{}


Related articles: