#if NET20 || NET30 || !NET_4_6 // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; using System.Dynamic.Utils; namespace System.Linq.Expressions.Reimplement { /// /// Represents a catch statement in a try block. /// This must have the same return type (i.e., the type of ) as the try block it is associated with. /// [DebuggerTypeProxy(typeof(CatchBlockProxy))] public sealed class CatchBlock { private readonly Type _test; private readonly ParameterExpression _var; private readonly Expression _body; private readonly Expression _filter; internal CatchBlock(Type test, ParameterExpression variable, Expression body, Expression filter) { _test = test; _var = variable; _body = body; _filter = filter; } /// /// Gets a reference to the object caught by this handler. /// public ParameterExpression Variable { get { return _var; } } /// /// Gets the type of this handler catches. /// public Type Test { get { return _test; } } /// /// Gets the body of the catch block. /// public Expression Body { get { return _body; } } /// /// Gets the body of the 's filter. /// public Expression Filter { get { return _filter; } } /// /// Returns a that represents the current . /// /// A that represents the current . public override string ToString() { return ExpressionStringBuilder.CatchBlockToString(this); } /// /// 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. /// /// The property of the result. /// The property of the result. /// The property of the result. /// This expression if no children changed, or an expression with the updated children. 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 { /// /// Creates a representing a catch statement. /// The of object to be caught can be specified but no reference to the object /// will be available for use in the . /// /// The of this will handle. /// The body of the catch statement. /// The created . public static CatchBlock Catch(Type type, Expression body) { return MakeCatchBlock(type, null, body, null); } /// /// Creates a representing a catch statement with a reference to the caught object for use in the handler body. /// /// A representing a reference to the object caught by this handler. /// The body of the catch statement. /// The created . public static CatchBlock Catch(ParameterExpression variable, Expression body) { ContractUtils.RequiresNotNull(variable, "variable"); return MakeCatchBlock(variable.Type, variable, body, null); } /// /// Creates a representing a catch statement with /// an filter but no reference to the caught object. /// /// The of this will handle. /// The body of the catch statement. /// The body of the filter. /// The created . public static CatchBlock Catch(Type type, Expression body, Expression filter) { return MakeCatchBlock(type, null, body, filter); } /// /// Creates a representing a catch statement with /// an filter and a reference to the caught object. /// /// A representing a reference to the object caught by this handler. /// The body of the catch statement. /// The body of the filter. /// The created . public static CatchBlock Catch(ParameterExpression variable, Expression body, Expression filter) { ContractUtils.RequiresNotNull(variable, "variable"); return MakeCatchBlock(variable.Type, variable, body, filter); } /// /// Creates a representing a catch statement with the specified elements. /// /// The of this will handle. /// A representing a reference to the object caught by this handler. /// The body of the catch statement. /// The body of the filter. /// The created . /// must be non-null and match the type of (if it is supplied). public static CatchBlock MakeCatchBlock(Type type, ParameterExpression variable, Expression body, Expression filter) { ContractUtils.RequiresNotNull(type, "type"); ContractUtils.Requires(variable == null || variable.Type == type, "variable"); if (variable != null && variable.IsByRef) { throw Error.VariableMustNotBeByRef(variable, variable.Type); } RequiresCanRead(body, "body"); if (filter != null) { RequiresCanRead(filter, "filter"); if (filter.Type != typeof(bool)) { throw Error.ArgumentMustBeBoolean(); } } return new CatchBlock(type, variable, body, filter); } } } #endif