• C#入门(11):泛型介绍


    C# 中的泛型(Generics)是一种强类型参数化的特性,它允许你编写不具体指定数据类型的代码,而在实际使用时再指定具体的类型。泛型的引入使得代码更加灵活、可重用,并提高了类型安全性。

    C#泛型基本用法

    以下是一个简单的 C# 泛型代码示例,展示了如何定义泛型类和泛型方法,以及如何使用泛型来创建通用的数据结构。

    using System;
    using System.Collections.Generic;
    
    // 泛型类示例
    public class GenericClass<T>
    {
        private T genericField;
    
        public GenericClass(T value)
        {
            this.genericField = value;
        }
    
        public T GetValue()
        {
            return genericField;
        }
    }
    
    // 泛型方法示例
    public class GenericMethod
    {
        public T GenericMethodExample<T>(T value)
        {
            Console.WriteLine($"Received value of type {typeof(T)}: {value}");
            return value;
        }
    }
    
    // 泛型接口示例
    public interface IGenericInterface<T>
    {
        void PrintValue(T value);
    }
    
    // 泛型集合示例
    public class GenericCollectionExample
    {
        public void ShowGenericList()
        {
            List<int> intList = new List<int> { 1, 2, 3, 4, 5 };
            List<string> stringList = new List<string> { "apple", "orange", "banana" };
    
            PrintList(intList);
            PrintList(stringList);
        }
    
        private void PrintList<T>(List<T> list)
        {
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
        }
    }
    
    class Program
    {
        static void Main()
        {
            // 使用泛型类
            GenericClass<int> intGenericClass = new GenericClass<int>(42);
            int intValue = intGenericClass.GetValue();
            Console.WriteLine($"GenericClass value: {intValue}");
    
            GenericClass<string> stringGenericClass = new GenericClass<string>("Hello, Generics!");
            string stringValue = stringGenericClass.GetValue();
            Console.WriteLine($"GenericClass value: {stringValue}");
    
            // 使用泛型方法
            GenericMethod genericMethod = new GenericMethod();
            genericMethod.GenericMethodExample(123);
            genericMethod.GenericMethodExample("Generic Method");
    
            // 使用泛型接口
            GenericInterfaceImplementation<int> genericInterfaceImpl = new GenericInterfaceImplementation<int>();
            genericInterfaceImpl.PrintValue(123);
    
            // 使用泛型集合
            GenericCollectionExample collectionExample = new GenericCollectionExample();
            collectionExample.ShowGenericList();
        }
    }
    
    // 实现泛型接口
    public class GenericInterfaceImplementation<T> : IGenericInterface<T>
    {
        public void PrintValue(T value)
        {
            Console.WriteLine($"Received value of type {typeof(T)}: {value}");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    在上面的示例中,GenericClass 是一个泛型类,可以用不同的类型实例化。GenericMethod 是一个包含泛型方法的类,可以在调用时指定不同的类型。IGenericInterface 是一个泛型接口,它定义了一个方法,实现类 GenericInterfaceImplementation 实现了这个接口并指定了具体的类型。GenericCollectionExample 展示了如何使用泛型集合(这里使用了 List)。

    通过使用泛型,你可以写出更加通用、灵活、类型安全的代码,同时减少了代码的冗余。

    泛型方法详细介绍

    在C#中,泛型方法是一种允许你在方法中使用一个或多个类型参数的方法。泛型方法可以在类、结构体、接口和委托中定义,并且能够提供更灵活、通用的代码,同时保持类型安全。

    以下是一个简单的泛型方法的示例:

    public class GenericMethodExample
    {
        // 泛型方法示例
        public T GenericMethod<T>(T value)
        {
            Console.WriteLine($"Received value of type {typeof(T)}: {value}");
            return value;
        }
    }
    
    class Program
    {
        static void Main()
        {
            GenericMethodExample example = new GenericMethodExample();
    
            // 调用泛型方法时可以显式指定类型参数
            int intValue = example.GenericMethod<int>(42);
    
            // 编译器可以自动推断类型参数
            string stringValue = example.GenericMethod("Hello, Generics!");
    
            // 泛型方法可以处理不同类型的参数
            double doubleValue = example.GenericMethod(3.14);
    
            // 泛型方法也可以用于引用类型
            List<int> intList = new List<int> { 1, 2, 3 };
            example.GenericMethod(intList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这个例子中,GenericMethod 是一个泛型方法,它使用了类型参数 T。当调用这个方法时,可以显式指定类型参数,也可以让编译器根据参数类型自动推断类型参数。这使得这个方法可以用于处理不同类型的数据,而无需为每个数据类型都编写一个单独的方法。

    泛型方法的优势在于它们提供了一种更灵活、通用的方式来处理数据,同时保持了类型安全。泛型方法在集合操作、算法实现以及其他需要通用性的场景中特别有用。

    泛型其它用法

    除了基本的泛型类、泛型方法和泛型接口之外,C# 还提供了一些更高级的泛型用法,包括泛型约束、泛型委托、协变和逆变等。下面是一些高级的泛型用法示例:

    泛型约束(Generic Constraints):

    泛型约束用于限制泛型类型参数的类型。常见的约束有 where T : 类型,它表示 T 必须是指定类型或其派生类。以下是一个示例:

    public class GenericConstraintExample<T> where T : class
    {
        public void PrintTypeName(T value)
        {
            Console.WriteLine($"Type of the value: {typeof(T)}");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这个例子中,where T : class 表示泛型类型参数 T 必须是引用类型。

    泛型委托(Generic Delegates):

    你可以使用泛型委托来创建通用的委托,使其能够处理不同类型的方法。以下是一个使用泛型委托的示例:

    public delegate void GenericDelegate<T>(T value);
    
    public class GenericDelegateExample
    {
        public void PrintInt(int x)
        {
            Console.WriteLine($"PrintInt: {x}");
        }
    
        public void PrintString(string s)
        {
            Console.WriteLine($"PrintString: {s}");
        }
    }
    
    class Program
    {
        static void Main()
        {
            GenericDelegateExample example = new GenericDelegateExample();
            GenericDelegate<int> intDelegate = example.PrintInt;
            GenericDelegate<string> stringDelegate = example.PrintString;
    
            intDelegate(42);
            stringDelegate("Hello, Generics!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    协变和逆变(Covariance and Contravariance):

    协变和逆变是与泛型接口和委托一起使用的高级概念,允许你使用派生类型替代基类型(协变)或使用基类型替代派生类型(逆变)。以下是一个协变的示例:

    public interface IMyInterface<out T>
    {
        T GetItem();
    }
    
    public class MyImplementation<T> : IMyInterface<T>
    {
        private T item;
    
        public MyImplementation(T item)
        {
            this.item = item;
        }
    
        public T GetItem()
        {
            return item;
        }
    }
    
    class Program
    {
        static void Main()
        {
            IMyInterface<string> stringInterface = new MyImplementation<string>("Hello, Covariance!");
            IMyInterface<object> objectInterface = stringInterface;
    
            Console.WriteLine(objectInterface.GetItem()); // 输出: Hello, Covariance!
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这个例子中,IMyInterface 使用了 out 关键字,表示协变。这使得我们可以将 IMyInterface 赋值给 IMyInterface

    这只是 C# 中一些高级泛型用法的简单示例。泛型约束、泛型委托、协变和逆变等概念可以帮助你更灵活地设计和使用泛型代码。

  • 相关阅读:
    Docker数据卷和网络管理 下
    JTAG基本介绍
    基于SSH一些相关的命令
    Nginx Note(01)——Nginx简介、优点和用途
    大数据学习(2)Hadoop-分布式资源计算hive(1)
    Linux服务器搭建Docker
    09_一种比较高效的记忆方法
    详解 IP 协议
    基于kubernetes CI/CD实践
    标量、向量、矩阵、张量之间的区别和联系
  • 原文地址:https://blog.csdn.net/yao_hou/article/details/134452779