#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