when(C# 参考)when (C# Reference)

在以下两个上下文中,可以使用上下文关键字 when 指定筛选条件:You can use the when contextual keyword to specify a filter condition in two contexts:

catch 语句中的 whenwhen in a catch statement

从 C# 6 开始,when 可用于 catch 语句中,以指定为执行特定异常处理程序而必须为 true 的条件。Starting with C# 6, when can be used in a catch statement to specify a condition that must be true for the handler for a specific exception to execute. 语法为:Its syntax is:

catch (ExceptionType [e]) when (expr)

其中,expr 是一个表达式,其计算结果为布尔值。where expr is an expression that evaluates to a Boolean value. 如果该表达式返回 true,则执行异常处理程序;如果返回 false,则不执行。If it returns true, the exception handler executes; if false, it does not.

以下示例使用 when 关键字有条件地执行 HttpRequestException 的处理程序,具体取决于异常消息的文本内容。The following example uses the when keyword to conditionally execute handlers for an HttpRequestException depending on the text of the exception message.

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Console.WriteLine(MakeRequest().Result);
    }

    public static async Task<string> MakeRequest()
    { 
        var client = new HttpClient();
        var streamTask = client.GetStringAsync("https://localHost:10000");
        try
        {
            var responseText = await streamTask;
            return responseText;
        } 
        catch (HttpRequestException e) when (e.Message.Contains("301"))
        {
            return "Site Moved";
        }
        catch (HttpRequestException e) when (e.Message.Contains("404"))
        {
            return "Page Not Found";
        }
        catch (HttpRequestException e)
        {
            return e.Message;
        }
    }
}

switch 语句中的 whenwhen in a switch statement

从 C# 7.0 开始,case 标签无需是互斥的,且 case 标签在 switch 语句中的显示顺序可以决定要执行的 switch 块。Starting with C# 7.0, case labels no longer need be mutually exclusive, and the order in which case labels appear in a switch statement can determine which switch block executes. when 关键字可指定一个筛选条件,该条件使得仅当筛选条件也为 true 时,与其相关联的 case 标签才为 true。The when keyword can be used to specify a filter condition that causes its associated case label to be true only if the filter condition is also true. 语法为:Its syntax is:

case (expr) when (when-condition):

其中,expr 是与匹配表达式进行比较的常量模式或类型模式,而 when-condition 是任意布尔表达式。where expr is a constant pattern or type pattern that is compared to the match expression, and when-condition is any Boolean expression.

以下示例使用 when 关键字针对具有零范围的 Shape 对象进行测试,同时针对各种范围大于零的 Shape 对象进行测试。The following example uses the when keyword to test for Shape objects that have an area of zero, as well as to test for a variety of Shape objects that have an area greater than zero.

using System;

public abstract class Shape
{
   public abstract double Area { get; }
   public abstract double Circumference { get; } 
}

public class Rectangle : Shape
{
   public Rectangle(double length, double width) 
   {
      Length = length;
      Width = width; 
   }

   public double Length { get; set; }
   public double Width { get; set; }
   
   public override double Area
   { 
      get { return Math.Round(Length * Width,2); } 
   } 
   
   public override double Circumference 
   {
      get { return (Length + Width) * 2; }
   }
}

public class Square : Rectangle
{
   public Square(double side) : base(side, side) 
   {
      Side = side; 
   }

   public double Side { get; set; }
}

public class Example
{
   public static void Main()
   {
      Shape sh = null;
      Shape[] shapes = { new Square(10), new Rectangle(5, 7),
                         new Rectangle(10, 10), sh, new Square(0) };
      foreach (var shape in shapes)
         ShowShapeInfo(shape);
   }

   private static void ShowShapeInfo(Object obj)
   {
      switch (obj)
      {
         case Shape shape when shape.Area == 0:
            Console.WriteLine($"The shape: {shape.GetType().Name} with no dimensions");
            break;
         case Square sq when sq.Area > 0:
            Console.WriteLine("Information about the square:");
            Console.WriteLine($"   Length of a side: {sq.Side}");
            Console.WriteLine($"   Area: {sq.Area}");
            break;
         case Rectangle r when r.Area > 0:
            Console.WriteLine("Information about the rectangle:");
            Console.WriteLine($"   Dimensions: {r.Length} x {r.Width}");
            Console.WriteLine($"   Area: {r.Area}");
            break;
         case Shape shape:
            Console.WriteLine($"A {shape.GetType().Name} shape");
            break;
         case null:
            Console.WriteLine($"The {nameof(obj)} variable is uninitialized.");
            break;
         default:
            Console.WriteLine($"The {nameof(obj)} variable does not represent a Shape.");
            break;   
      }
   }
}
// The example displays the following output:
//       Information about the square:
//          Length of a side: 10
//          Area: 100
//       Information about the rectangle:
//          Dimensions: 5 x 7
//          Area: 35
//       Information about the rectangle:
//          Dimensions: 10 x 10
//          Area: 100
//       The obj variable is uninitialized.
//       The shape: Square with no dimensions

请参阅See also