在 C# 中,delegate 是一种引用类型,它允许您定义和使用可以引用特定方法的对象。delegate 可以看作是一种函数指针,它可以在运行时动态地调用不同的方法。
以下是一个简单的例子来说明 delegate 的实际作用:
// 1. 定义一个 delegate 类型
delegate void PrintDelegate(string message);
class Program
{
// 2. 声明一个 delegate 类型的变量
static PrintDelegate printDelegate;
static void Main(string[] args)
{
// 3. 使用 delegate 变量来引用一个方法
printDelegate = PrintMessage;
// 4. 使用 delegate 变量来调用引用的方法
printDelegate("Hello, World!");
}
static void PrintMessage(string message)
{
Console.WriteLine(message);
}
}
在上面的示例中,我们首先定义了一个 delegate 类型 PrintDelegate
,它可以引用一个具有一个 string
参数和无返回值的方法。然后,在 Main
方法中,我们声明了一个名为 printDelegate
的变量,该变量具有 PrintDelegate
类型,并将其赋值为 PrintMessage
方法。最后,我们通过调用 printDelegate
变量来调用 PrintMessage
方法,并传递了一个字符串参数。
这样做的好处是,通过使用 delegate,我们可以将方法作为一个参数传递给其他方法,或者将其存储在变量中,以便在稍后的代码中调用它。这样可以使我们的代码更加灵活和可复用。
泛型委托是一种允许指定不同类型的方法作为参数的委托。它可以提供更大的灵活性和重用性,因为您可以在运行时根据需要指定方法的类型。
以下是一个简单的示例,展示了泛型委托的用法:
// 定义一个泛型委托
delegate T MyGenericDelegate(T param);
// 泛型方法,将传入的值加倍
static int DoubleValue(int value)
{
return value * 2;
}
// 泛型方法,将传入的字符串转换为大写
static string ConvertToUpper(string value)
{
return value.ToUpper();
}
static void Main()
{
// 创建一个使用了泛型委托的实例
MyGenericDelegate doubleDelegate = DoubleValue;
MyGenericDelegate upperDelegate = ConvertToUpper;
// 使用泛型委托调用方法
int result1 = doubleDelegate(5); // 返回10
string result2 = upperDelegate("hello"); // 返回"HELLO"
Console.WriteLine(result1);
Console.WriteLine(result2);
}
主要重点是:约束可以是其派生类
在C#中,泛型约束是一种限制泛型类型参数的方法。通过使用泛型约束,我们可以指定泛型类型必须满足特定的条件或实现特定的接口。这可以帮助我们在编译时捕获错误并提供更安全的编程体验。
泛型约束通过使用where
关键字来声明。以下是一些常见的泛型约束类型:
类型约束:指定泛型类型必须是特定的类或结构体。
public class MyClass where T : SomeClass
在此示例中,T
必须是SomeClass
或其任何派生类。
接口约束:指定泛型类型必须实现特定的接口。
public class MyClass where T : ISomeInterface
在此示例中,T
必须实现ISomeInterface
接口。
构造函数约束:指定泛型类型必须具有无参构造函数。
public class MyClass where T : new()
在此示例中,T
必须具有无参构造函数。
下面是一个简单的例子,演示如何在泛型约束中使用类型和接口约束:
public interface IShape
{
double CalculateArea();
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double CalculateArea()
{
return Width * Height;
}
}
public class Circle : IShape
{
public double Radius { get; set; }
public double CalculateArea()
{
return Math.PI * Radius * Radius;
}
}
public class Calculator where T : IShape
{
public double CalculateTotalArea(T[] shapes)
{
double totalArea = 0;
foreach (T shape in shapes)
{
totalArea += shape.CalculateArea();
}
return totalArea;
}
}
在此示例中,Calculator
类的泛型类型参数T
必须实现IShape
接口。CalculateTotalArea
方法接受一个泛型数组参数,并使用每个元素的CalculateArea
方法来计算总面积。
使用示例:
Rectangle rectangle1 = new Rectangle() { Width = 5, Height = 10 };
Rectangle rectangle2 = new Rectangle() { Width = 3, Height = 6 };
Circle circle = new Circle() { Radius = 7 };
Calculator rectangleCalculator = new Calculator();
double rectangleTotalArea = rectangleCalculator.CalculateTotalArea(new Rectangle[] { rectangle1, rectangle2 });
Calculator circleCalculator = new Calculator();
double circleTotalArea = circleCalculator.CalculateTotalArea(new Circle[] { circle });
在上面的示例中,我们创建了一个Rectangle和一个Circle对象,并分别计算了它们的总面积。由于我们使用了泛型约束,计算器类只能用于实现IShape接口的类型。