| File: System\Linq\Expressions\CatchBlock.cs | Web Access |
| Project: src\runtime\src\libraries\System.Linq.Expressions\src\System.Linq.Expressions.csproj (System.Linq.Expressions) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Dynamic.Utils; namespace System.Linq.Expressions { /// <summary> /// Represents a catch statement in a try block. /// This must have the same return type (i.e., the type of <see cref="Body"/>) as the try block it is associated with. /// </summary> [DebuggerTypeProxy(typeof(Expression.CatchBlockProxy))] public sealed class CatchBlock { internal CatchBlock(Type test, ParameterExpression? variable, Expression body, Expression? filter) { Test = test; Variable = variable; Body = body; Filter = filter; } /// <summary> /// Gets a reference to the <see cref="Exception"/> object caught by this handler. /// </summary> public ParameterExpression? Variable { get; } /// <summary> /// Gets the type of <see cref="Exception"/> this handler catches. /// </summary> public Type Test { get; } /// <summary> /// Gets the body of the catch block. /// </summary> public Expression Body { get; } /// <summary> /// Gets the body of the <see cref="CatchBlock"/>'s filter. /// </summary> public Expression? Filter { get; } /// <summary> /// Returns a <see cref="string"/> that represents the current <see cref="object"/>. /// </summary> /// <returns>A <see cref="string"/> that represents the current <see cref="object"/>.</returns> public override string ToString() { return ExpressionStringBuilder.CatchBlockToString(this); } /// <summary> /// Creates a new expression that is like this one, but using the /// supplied children. If all of the children are the same, it will /// return this expression. /// </summary> /// <param name="variable">The <see cref="Variable"/> property of the result.</param> /// <param name="filter">The <see cref="Filter"/> property of the result.</param> /// <param name="body">The <see cref="Body"/> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public CatchBlock Update(ParameterExpression? variable, Expression? filter, Expression body) { if (variable == Variable && filter == Filter && body == Body) { return this; } return Expression.MakeCatchBlock(Test, variable, body, filter); } } public partial class Expression { /// <summary> /// Creates a <see cref="CatchBlock"/> representing a catch statement. /// The <see cref="Type"/> of object to be caught can be specified but no reference to the object /// will be available for use in the <see cref="CatchBlock"/>. /// </summary> /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param> /// <param name="body">The body of the catch statement.</param> /// <returns>The created <see cref="CatchBlock"/>.</returns> public static CatchBlock Catch(Type type, Expression body) { return MakeCatchBlock(type, null, body, filter: null); } /// <summary> /// Creates a <see cref="CatchBlock"/> representing a catch statement with a reference to the caught object for use in the handler body. /// </summary> /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param> /// <param name="body">The body of the catch statement.</param> /// <returns>The created <see cref="CatchBlock"/>.</returns> public static CatchBlock Catch(ParameterExpression variable, Expression body) { ArgumentNullException.ThrowIfNull(variable); return MakeCatchBlock(variable.Type, variable, body, filter: null); } /// <summary> /// Creates a <see cref="CatchBlock"/> representing a catch statement with /// an <see cref="Exception"/> filter but no reference to the caught <see cref="Exception"/> object. /// </summary> /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param> /// <param name="body">The body of the catch statement.</param> /// <param name="filter">The body of the <see cref="Exception"/> filter.</param> /// <returns>The created <see cref="CatchBlock"/>.</returns> public static CatchBlock Catch(Type type, Expression body, Expression? filter) { return MakeCatchBlock(type, null, body, filter); } /// <summary> /// Creates a <see cref="CatchBlock"/> representing a catch statement with /// an <see cref="Exception"/> filter and a reference to the caught <see cref="Exception"/> object. /// </summary> /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param> /// <param name="body">The body of the catch statement.</param> /// <param name="filter">The body of the <see cref="Exception"/> filter.</param> /// <returns>The created <see cref="CatchBlock"/>.</returns> public static CatchBlock Catch(ParameterExpression variable, Expression body, Expression? filter) { ArgumentNullException.ThrowIfNull(variable); return MakeCatchBlock(variable.Type, variable, body, filter); } /// <summary> /// Creates a <see cref="CatchBlock"/> representing a catch statement with the specified elements. /// </summary> /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param> /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param> /// <param name="body">The body of the catch statement.</param> /// <param name="filter">The body of the <see cref="Exception"/> filter.</param> /// <returns>The created <see cref="CatchBlock"/>.</returns> /// <remarks><paramref name="type"/> must be non-null and match the type of <paramref name="variable"/> (if it is supplied).</remarks> public static CatchBlock MakeCatchBlock(Type type, ParameterExpression? variable, Expression body, Expression? filter) { ArgumentNullException.ThrowIfNull(type); ContractUtils.Requires(variable == null || TypeUtils.AreEquivalent(variable.Type, type), nameof(variable)); if (variable == null) { TypeUtils.ValidateType(type, nameof(type)); } else if (variable.IsByRef) { throw Error.VariableMustNotBeByRef(variable, variable.Type, nameof(variable)); } ExpressionUtils.RequiresCanRead(body, nameof(body)); if (filter != null) { ExpressionUtils.RequiresCanRead(filter, nameof(filter)); if (filter.Type != typeof(bool)) throw Error.ArgumentMustBeBoolean(nameof(filter)); } return new CatchBlock(type, variable, body, filter); } } }