C# 泛型允许我们创建可以使用不同类型数据的单个类或方法。这有助于我们重用代码。
在这里,我们将学习如何在 C# 中创建泛型类和泛型方法。
C# 泛型类
泛型类用于创建任何数据类型的实例。要定义一个泛型类,我们使用尖括号 (<>
) 如下:
class Student<T>
{
// block of code
}
在这里,我们创建了一个名为 Student
的泛型类。尖括号内的 T
被称为类型参数。
在创建类的实例时,我们指定对象的数据类型,该数据类型将替换类型参数。
创建泛型类实例
让我们创建泛型类的两个实例。
// create an instance with data type string
Student<string> studentName = new Student<string>();
// create an instance with data type int
Student<int> studentId = new Student<int>();
在这里,我们创建了两个实例,分别名为 studentName
和 studentId
,其数据类型分别为 string
和 int
。
在编译时,Student
类的类型参数 T
将被替换为:
string
- 对于实例studentName
int
- 对于实例studentId
示例:C# 泛型类
using System;
// define a generics class named Student
public class Student<T>
{
// define a variable of type T
public T data;
// define a constructor of the Student class
public Student(T data)
{
this.data = data;
Console.WriteLine("Data passed: " + this.data);
}
}
class Program
{
static void Main()
{
// create an instance with data type string
Student<string> studentName = new Student<string>("Avicii");
// create an instance with data type int
Student<int> studentId = new Student<int>(23);
}
}
输出
Data passed: Avicii Data passed: 23
在上面的示例中,我们创建了一个名为 Student
的泛型类。此外,我们还定义了一个 构造函数 来打印 this
的值。
在 Main
类中,我们创建了 Student
类的两个实例:studentName
和 studentId
。
Student<T>
的类型参数 T
被替换为
string
- 在studentName
中int
- 在studentId
中
在这里,Student
类同时适用于 int
和 string
数据类型。
C# 泛型方法
与泛型类类似,我们还可以创建可以使用任何类型数据的方法。这样的类称为泛型方法。例如:
public void displayData(T data) {
Console.WriteLine("Data Passed: " + data);
}
这里,
displayData
- 泛型方法的名称T
- 类型参数,用于指定函数可以接受任何类型的数据data
- 函数参数
现在我们可以使用此函数来处理任何类型的数据。例如:
// calling function with integer data
obj.displayData(34);
// calling function with string data
obj.displayData("Tim");
示例:C# 泛型方法
using System;
// define a generics class named Employee
class Employee<T>
{
// define a generics method that displays the passed data
public void displayData(T data)
{
Console.WriteLine("The data passed is: " + data);
}
}
class Program
{
static void Main()
{
// create an instance of Employee class by specifying T as string
Employee<string> employeeName = new Employee<string>();
// call displayData() generics method and pass a string value - "Jack"
employeeName.displayData("Jack");
// create an instance of Employee class by specifying T as int
Employee<int> employeeId = new Employee<int>();
// call displayData() generics method and pass an integer value
employeeId.displayData(123);
}
}
输出
The data passed is: Jack The data passed is: 123
在上面的示例中,我们在 Employee<T>
泛型类中定义了一个名为 displayData()
的泛型方法。
示例:带返回类型的泛型方法
前面我们定义了一个不带返回类型的泛型方法。但是,我们也可以定义一个带返回类型的泛型方法。例如:
using System;
// define a generics class named Employee
class Movie<T>
{
// define a generics method that returns T type value
public T displayData(T data)
{
return data;
}
}
class Program
{
static void Main()
{
// create an instance with data type string
Movie<string> movieName = new Movie<string>();
Console.WriteLine("Generics Method returns: " + movieName.displayData("Inception"));
// create an instance with data type int
Movie<int> movieRating = new Movie<int>();
Console.WriteLine("Generics Method returns: " + movieRating.displayData(9));
}
}
输出
Generics Method returns: Inception Generics Method returns: 9
在上面的示例中,我们创建了一个名为 displayData()
的泛型方法。请注意,我们使用了 T
作为返回类型,而不是 void。
这意味着该方法可以返回任何类型的值。
public T displayData(T data) {...}
在本例中,该方法返回:
string
数据 -"Inception"
int
数据 - 9
泛型的优点
1.代码重用性
借助 C# 中的泛型,我们可以编写适用于不同类型数据的代码。例如:
public void displayData(T data) {...}
在这里,我们创建了一个泛型方法。此方法可用于对整数数据、字符串数据等执行操作。
2.编译时类型检查
泛型的类型参数提供了有关泛型代码中使用的数据类型的信息。例如:
// int type instance of GenericsClass
GenericsClass<int> list = new GenericsClass<>();
在这里,我们知道 GenericsClass
只适用于 int
数据。
现在,如果我们尝试将非 int
数据传递给此类,程序将在编译时生成错误。
3.与集合一起使用
集合框架在 C# 中使用了泛型的概念。例如:
// create a string type List
List<string> courseName = new List<string>();
// create an int type List
List<int> courseId = new List<int>();
在上面的示例中,我们使用了相同的 List
类来处理不同类型的数据。
与 List
类似,C# 中的其他集合(Queue
、Stack
等)也是泛型的。
常见问题
我们也可以在非泛型类中定义泛型方法。例如:
using System;
// create a non-generic class named Gadget
public class Gadget
{
// define a generic method
public T displayData<T>(T data)
{
return data;
}
}
class Program
{
static void Main()
{
Gadget gadgetName = new Gadget();
// call generic method displayData() and pass string data
Console.WriteLine("Generic Method returns: " + gadgetName.displayData("Laptop"));
Gadget gadgetModel = new Gadget();
// call generic method displayData() and pass integer data
Console.WriteLine("Generic Method returns: " + gadgetModel.displayData(513));
}
}
输出
Generic Method returns: Laptop Generic Method returns: 513
在上面的示例中,我们在名为 Gadget
的非泛型类中创建了一个名为 displayData()
的泛型方法。请注意代码:
public T displayData<T>(T data) {...}
在这里,我们需要使用 <T>
在没有泛型类的情况下定义一个泛型方法 displayData()
。
在 C# 中,我们还可以创建泛型属性。例如:
using System;
public class Sport<T>
{
// define a generic field
public T data;
// define a generic property
public T Data
{
get { return data; }
set { data = value; }
}
}
class Program
{
static void Main()
{
// create an instance of Sport with data type string
Sport<string> sportName = new Sport<string>();
// access the generic property, Data
sportName.Data = "Football";
Console.WriteLine("Name of Sport is : " + sportName.Data);
}
}
输出
Name of Sport is : Football
在这里,我们定义了一个名为 Data
的泛型属性。
注意: 泛型不仅可以用于属性、类或方法,还可以用于抽象类、接口、事件、委托等。