Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Ast / UnaryExpression.cs / 1305376 / UnaryExpression.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Diagnostics; using System.Dynamic.Utils; using System.Reflection; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ////// Represents an expression that has a unary operator. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.UnaryExpressionProxy))] #endif public sealed class UnaryExpression : Expression { private readonly Expression _operand; private readonly MethodInfo _method; private readonly ExpressionType _nodeType; private readonly Type _type; internal UnaryExpression(ExpressionType nodeType, Expression expression, Type type, MethodInfo method) { _operand = expression; _method = method; _nodeType = nodeType; _type = type; } ////// Gets the static type of the expression that this ///represents. (Inherited from .) /// The public sealed override Type Type { get { return _type; } } ///that represents the static type of the expression. /// Returns the node type of this ///. (Inherited from .) /// The public sealed override ExpressionType NodeType { get { return _nodeType; } } ///that represents this expression. /// Gets the operand of the unary operation. /// ///An public Expression Operand { get { return _operand; } } ///that represents the operand of the unary operation. /// Gets the implementing method for the unary operation. /// ///The public MethodInfo Method { get { return _method; } } ///that represents the implementing method. /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator. /// ///true if the node represents a lifted call; otherwise, false. public bool IsLifted { get { if (NodeType == ExpressionType.TypeAs || NodeType == ExpressionType.Quote || NodeType == ExpressionType.Throw) { return false; } bool operandIsNullable = TypeUtils.IsNullableType(_operand.Type); bool resultIsNullable = TypeUtils.IsNullableType(this.Type); if (_method != null) { return (operandIsNullable && !TypeUtils.AreEquivalent(_method.GetParametersCached()[0].ParameterType, _operand.Type)) || (resultIsNullable && !TypeUtils.AreEquivalent(_method.ReturnType, this.Type)); } return operandIsNullable || resultIsNullable; } } ////// Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type. /// ///true if the operator's return type is lifted to a nullable type; otherwise, false. public bool IsLiftedToNull { get { return IsLifted && TypeUtils.IsNullableType(this.Type); } } ////// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitUnary(this); } ////// Gets a value that indicates whether the expression tree node can be reduced. /// public override bool CanReduce { get { switch (_nodeType) { case ExpressionType.PreIncrementAssign: case ExpressionType.PreDecrementAssign: case ExpressionType.PostIncrementAssign: case ExpressionType.PostDecrementAssign: return true; } return false; } } ////// Reduces the expression node to a simpler expression. /// If CanReduce returns true, this should return a valid expression. /// This method is allowed to return another node which itself /// must be reduced. /// ///The reduced expression. public override Expression Reduce() { if (CanReduce) { switch (_operand.NodeType) { case ExpressionType.Index: return ReduceIndex(); case ExpressionType.MemberAccess: return ReduceMember(); default: return ReduceVariable(); } } return this; } private bool IsPrefix { get { return _nodeType == ExpressionType.PreIncrementAssign || _nodeType == ExpressionType.PreDecrementAssign; } } private UnaryExpression FunctionalOp(Expression operand) { ExpressionType functional; if (_nodeType == ExpressionType.PreIncrementAssign || _nodeType == ExpressionType.PostIncrementAssign) { functional = ExpressionType.Increment; } else { functional = ExpressionType.Decrement; } return new UnaryExpression(functional, operand, operand.Type, _method); } private Expression ReduceVariable() { if (IsPrefix) { // (op) var // ... is reduced into ... // var = op(var) return Assign(_operand, FunctionalOp(_operand)); } // var (op) // ... is reduced into ... // temp = var // var = op(var) // temp var temp = Parameter(_operand.Type, null); return Block( new[] { temp }, Assign(temp, _operand), Assign(_operand, FunctionalOp(temp)), temp ); } private Expression ReduceMember() { var member = (MemberExpression)_operand; if (member.Expression == null) { //static member, reduce the same as variable return ReduceVariable(); } else { var temp1 = Parameter(member.Expression.Type, null); var initTemp1 = Assign(temp1, member.Expression); member = MakeMemberAccess(temp1, member.Member); if (IsPrefix) { // (op) value.member // ... is reduced into ... // temp1 = value // temp1.member = op(temp1.member) return Block( new[] { temp1 }, initTemp1, Assign(member, FunctionalOp(member)) ); } // value.member (op) // ... is reduced into ... // temp1 = value // temp2 = temp1.member // temp1.member = op(temp2) // temp2 var temp2 = Parameter(member.Type, null); return Block( new[] { temp1, temp2 }, initTemp1, Assign(temp2, member), Assign(member, FunctionalOp(temp2)), temp2 ); } } private Expression ReduceIndex() { // left[a0, a1, ... aN] (op) // // ... is reduced into ... // // tempObj = left // tempArg0 = a0 // ... // tempArgN = aN // tempValue = tempObj[tempArg0, ... tempArgN] // tempObj[tempArg0, ... tempArgN] = op(tempValue) // tempValue bool prefix = IsPrefix; var index = (IndexExpression)_operand; int count = index.Arguments.Count; var block = new Expression[count + (prefix ? 2 : 4)]; var temps = new ParameterExpression[count + (prefix ? 1 : 2)]; var args = new ParameterExpression[count]; int i = 0; temps[i] = Parameter(index.Object.Type, null); block[i] = Assign(temps[i], index.Object); i++; while (i <= count) { var arg = index.Arguments[i - 1]; args[i - 1] = temps[i] = Parameter(arg.Type, null); block[i] = Assign(temps[i], arg); i++; } index = MakeIndex(temps[0], index.Indexer, new TrueReadOnlyCollection(args)); if (!prefix) { var lastTemp = temps[i] = Parameter(index.Type, null); block[i] = Assign(temps[i], index); i++; Debug.Assert(i == temps.Length); block[i++] = Assign(index, FunctionalOp(lastTemp)); block[i++] = lastTemp; } else { Debug.Assert(i == temps.Length); block[i++] = Assign(index, FunctionalOp(index)); } Debug.Assert(i == block.Length); return Block(new TrueReadOnlyCollection (temps), new TrueReadOnlyCollection (block)); } /// /// 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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public UnaryExpression Update(Expression operand) { if (operand == Operand) { return this; } return Expression.MakeUnary(NodeType, operand, Type, Method); } } public partial class Expression { ////// Creates a /// The, given an operand, by calling the appropriate factory method. /// that specifies the type of unary operation. /// An that represents the operand. /// The that specifies the type to be converted to (pass null if not applicable). /// The ///that results from calling the appropriate factory method. Thrown when ///does not correspond to a unary expression. Thrown when public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type) { return MakeUnary(unaryType, operand, type, null); } ///is null. /// Creates a /// The, given an operand and implementing method, by calling the appropriate factory method. /// that specifies the type of unary operation. /// An that represents the operand. /// The that specifies the type to be converted to (pass null if not applicable). /// The that represents the implementing method. /// The ///that results from calling the appropriate factory method. Thrown when ///does not correspond to a unary expression. Thrown when [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type, MethodInfo method) { switch (unaryType) { case ExpressionType.Negate: return Negate(operand, method); case ExpressionType.NegateChecked: return NegateChecked(operand, method); case ExpressionType.Not: return Not(operand, method); case ExpressionType.IsFalse: return IsFalse(operand, method); case ExpressionType.IsTrue: return IsTrue(operand, method); case ExpressionType.OnesComplement: return OnesComplement(operand, method); case ExpressionType.ArrayLength: return ArrayLength(operand); case ExpressionType.Convert: return Convert(operand, type, method); case ExpressionType.ConvertChecked: return ConvertChecked(operand, type, method); case ExpressionType.Throw: return Throw(operand, type); case ExpressionType.TypeAs: return TypeAs(operand, type); case ExpressionType.Quote: return Quote(operand); case ExpressionType.UnaryPlus: return UnaryPlus(operand, method); case ExpressionType.Unbox: return Unbox(operand, type); case ExpressionType.Increment: return Increment(operand, method); case ExpressionType.Decrement: return Decrement(operand, method); case ExpressionType.PreIncrementAssign: return PreIncrementAssign(operand, method); case ExpressionType.PostIncrementAssign: return PostIncrementAssign(operand, method); case ExpressionType.PreDecrementAssign: return PreDecrementAssign(operand, method); case ExpressionType.PostDecrementAssign: return PostDecrementAssign(operand, method); default: throw Error.UnhandledUnary(unaryType); } } private static UnaryExpression GetUserDefinedUnaryOperatorOrThrow(ExpressionType unaryType, string name, Expression operand) { UnaryExpression u = GetUserDefinedUnaryOperator(unaryType, name, operand); if (u != null) { ValidateParamswithOperandsOrThrow(u.Method.GetParametersCached()[0].ParameterType, operand.Type, unaryType, name); return u; } throw Error.UnaryOperatorNotDefined(unaryType, operand.Type); } private static UnaryExpression GetUserDefinedUnaryOperator(ExpressionType unaryType, string name, Expression operand) { Type operandType = operand.Type; Type[] types = new Type[] { operandType }; Type nnOperandType = TypeUtils.GetNonNullableType(operandType); BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = nnOperandType.GetMethodValidated(name, flags, null, types, null); if (method != null) { return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // try lifted call if (TypeUtils.IsNullableType(operandType)) { types[0] = nnOperandType; method = nnOperandType.GetMethodValidated(name, flags, null, types, null); if (method != null && method.ReturnType.IsValueType && !TypeUtils.IsNullableType(method.ReturnType)) { return new UnaryExpression(unaryType, operand, TypeUtils.GetNullableType(method.ReturnType), method); } } return null; } private static UnaryExpression GetMethodBasedUnaryOperator(ExpressionType unaryType, Expression operand, MethodInfo method) { System.Diagnostics.Debug.Assert(method != null); ValidateOperator(method); ParameterInfo[] pms = method.GetParametersCached(); if (pms.Length != 1) throw Error.IncorrectNumberOfMethodCallArguments(method); if (ParameterIsAssignable(pms[0], operand.Type)) { ValidateParamswithOperandsOrThrow(pms[0].ParameterType, operand.Type, unaryType, method.Name); return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // check for lifted call if (TypeUtils.IsNullableType(operand.Type) && ParameterIsAssignable(pms[0], TypeUtils.GetNonNullableType(operand.Type)) && method.ReturnType.IsValueType && !TypeUtils.IsNullableType(method.ReturnType)) { return new UnaryExpression(unaryType, operand, TypeUtils.GetNullableType(method.ReturnType), method); } throw Error.OperandTypesDoNotMatchParameters(unaryType, method.Name); } private static UnaryExpression GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType) { UnaryExpression u = GetUserDefinedCoercion(coercionType, expression, convertToType); if (u != null) { return u; } throw Error.CoercionOperatorNotDefined(expression.Type, convertToType); } private static UnaryExpression GetUserDefinedCoercion(ExpressionType coercionType, Expression expression, Type convertToType) { MethodInfo method = TypeUtils.GetUserDefinedCoercionMethod(expression.Type, convertToType, false); if (method != null) { return new UnaryExpression(coercionType, expression, convertToType, method); } else { return null; } } private static UnaryExpression GetMethodBasedCoercionOperator(ExpressionType unaryType, Expression operand, Type convertToType, MethodInfo method) { System.Diagnostics.Debug.Assert(method != null); ValidateOperator(method); ParameterInfo[] pms = method.GetParametersCached(); if (pms.Length != 1) { throw Error.IncorrectNumberOfMethodCallArguments(method); } if (ParameterIsAssignable(pms[0], operand.Type) && TypeUtils.AreEquivalent(method.ReturnType, convertToType)) { return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // check for lifted call if ((TypeUtils.IsNullableType(operand.Type) || TypeUtils.IsNullableType(convertToType)) && ParameterIsAssignable(pms[0], TypeUtils.GetNonNullableType(operand.Type)) && TypeUtils.AreEquivalent(method.ReturnType, TypeUtils.GetNonNullableType(convertToType))) { return new UnaryExpression(unaryType, operand, convertToType, method); } throw Error.OperandTypesDoNotMatchParameters(unaryType, method.Name); } ///is null. /// Creates a /// Anthat represents an arithmetic negation operation. /// to set the property equal to. /// A ///that has the property equal to and the properties set to the specified value. Thrown when ///is null. Thrown when the unary minus operator is not defined for public static UnaryExpression Negate(Expression expression) { return Negate(expression, null); } ////// Creates a /// Anthat represents an arithmetic negation operation. /// to set the property equal to. /// A to set the property equal to. /// A ///that has the property equal to and the and properties set to the specified value. Thrown when ///is null. Thrown when ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. Thown when public static UnaryExpression Negate(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type) && !TypeUtils.IsUnsignedInt(expression.Type)) { return new UnaryExpression(ExpressionType.Negate, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Negate, "op_UnaryNegation", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Negate, expression, method); } ///is null and the unary minus operator is not defined for expression.Type or expression.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. /// Creates a /// Anthat represents a unary plus operation. /// to set the property equal to. /// A ///that has the property equal to and the property set to the specified value. Thrown when ///is null. Thown when the unary minus operator is not defined for expression.Type. public static UnaryExpression UnaryPlus(Expression expression) { return UnaryPlus(expression, null); } ////// Creates a /// Anthat represents a unary plus operation. /// to set the property equal to. /// A to set the property equal to. /// A ///that has the property equal to and the and property set to the specified value. Thrown when ///is null. Thrown when ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. Thown when public static UnaryExpression UnaryPlus(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.UnaryPlus, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.UnaryPlus, "op_UnaryPlus", expression); } return GetMethodBasedUnaryOperator(ExpressionType.UnaryPlus, expression, method); } ///is null and the unary minus operator is not defined for expression.Type or expression.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. Creates a ///that represents an arithmetic negation operation that has overflow checking. A /// Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// Thrown when ///is null. Thrown when the unary minus operator is not defined for public static UnaryExpression NegateChecked(Expression expression) { return NegateChecked(expression, null); } ///.Type. Creates a ///that represents an arithmetic negation operation that has overflow checking. The implementing method can be specified. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. /// public static UnaryExpression NegateChecked(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type) && !TypeUtils.IsUnsignedInt(expression.Type)) { return new UnaryExpression(ExpressionType.NegateChecked, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.NegateChecked, "op_UnaryNegation", expression); } return GetMethodBasedUnaryOperator(ExpressionType.NegateChecked, expression, method); } ///is null and the unary minus operator is not defined for .Type.-or- .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . Creates a ///that represents a bitwise complement operation. A ///Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// ///is null. The unary not operator is not defined for public static UnaryExpression Not(Expression expression) { return Not(expression, null); } ///.Type. Creates a ///that represents a bitwise complement operation. The implementing method can be specified. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. /// public static UnaryExpression Not(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsIntegerOrBool(expression.Type)) { return new UnaryExpression(ExpressionType.Not, expression, expression.Type, null); } UnaryExpression u = GetUserDefinedUnaryOperator(ExpressionType.Not, "op_LogicalNot", expression); if (u != null) { return u; } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Not, "op_OnesComplement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Not, expression, method); } ///is null and the unary not operator is not defined for .Type.-or- .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . /// Returns whether the expression evaluates to false. /// /// Anto evaluate. /// An instance of public static UnaryExpression IsFalse(Expression expression) { return IsFalse(expression, null); } ///. /// Returns whether the expression evaluates to false. /// ///Anto evaluate. ///A that represents the implementing method. /// An instance of public static UnaryExpression IsFalse(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsBool(expression.Type)) { return new UnaryExpression(ExpressionType.IsFalse, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.IsFalse, "op_False", expression); } return GetMethodBasedUnaryOperator(ExpressionType.IsFalse, expression, method); } ///. /// Returns whether the expression evaluates to true. /// /// Anto evaluate. /// An instance of public static UnaryExpression IsTrue(Expression expression) { return IsTrue(expression, null); } ///. /// Returns whether the expression evaluates to true. /// ///Anto evaluate. ///A that represents the implementing method. /// An instance of public static UnaryExpression IsTrue(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsBool(expression.Type)) { return new UnaryExpression(ExpressionType.IsTrue, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.IsTrue, "op_True", expression); } return GetMethodBasedUnaryOperator(ExpressionType.IsTrue, expression, method); } ///. /// Returns the expression representing the ones complement. /// ///An. /// An instance of public static UnaryExpression OnesComplement(Expression expression) { return OnesComplement(expression, null); } ///. /// Returns the expression representing the ones complement. /// /// An. /// A that represents the implementing method. /// An instance of public static UnaryExpression OnesComplement(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsInteger(expression.Type)) { return new UnaryExpression(ExpressionType.OnesComplement, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.OnesComplement, "op_OnesComplement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.OnesComplement, expression, method); } ///. Creates a ///that represents an explicit reference or boxing conversion where null is supplied if the conversion fails. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// public static UnaryExpression TypeAs(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (type.IsValueType && !TypeUtils.IsNullableType(type)) { throw Error.IncorrectTypeForTypeAs(type); } return new UnaryExpression(ExpressionType.TypeAs, expression, type, null); } ///or is null. /// /// AnCreates a ///that represents an explicit unboxing. to unbox. /// The new of the expression. /// An instance of public static UnaryExpression Unbox(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (!expression.Type.IsInterface && expression.Type != typeof(object)) { throw Error.InvalidUnboxType(); } if (!type.IsValueType) throw Error.InvalidUnboxType(); TypeUtils.ValidateType(type); return new UnaryExpression(ExpressionType.Unbox, expression, type, null); } ///. Creates a ///that represents a conversion operation. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///or is null. No conversion operator is defined between public static UnaryExpression Convert(Expression expression, Type type) { return Convert(expression, type, null); } ///.Type and . Creates a ///that represents a conversion operation for which the implementing method is specified. A ///Anthat has the property equal to and the , , and properties set to the specified values. to set the property equal to. ///A to set the property equal to. ///A to set the property equal to. /// /// ///or is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. More than one method that matches the ///description was found. No conversion operator is defined between public static UnaryExpression Convert(Expression expression, Type type, MethodInfo method) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (method == null) { if (TypeUtils.HasIdentityPrimitiveOrNullableConversion(expression.Type, type) || TypeUtils.HasReferenceConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.Convert, expression, type, null); } return GetUserDefinedCoercionOrThrow(ExpressionType.Convert, expression, type); } return GetMethodBasedCoercionOperator(ExpressionType.Convert, expression, type, method); } ///.Type and .-or- .Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or- .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . Creates a ///that represents a conversion operation that throws an exception if the target type is overflowed. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///or is null. No conversion operator is defined between public static UnaryExpression ConvertChecked(Expression expression, Type type) { return ConvertChecked(expression, type, null); } ///.Type and . Creates a ///that represents a conversion operation that throws an exception if the target type is overflowed and for which the implementing method is specified. A ///Anthat has the property equal to and the , , and properties set to the specified values. to set the property equal to. ///A to set the property equal to. ///A to set the property equal to. /// /// ///or is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. More than one method that matches the ///description was found. No conversion operator is defined between public static UnaryExpression ConvertChecked(Expression expression, Type type, MethodInfo method) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (method == null) { if (TypeUtils.HasIdentityPrimitiveOrNullableConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.ConvertChecked, expression, type, null); } if (TypeUtils.HasReferenceConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.Convert, expression, type, null); } return GetUserDefinedCoercionOrThrow(ExpressionType.ConvertChecked, expression, type); } return GetMethodBasedCoercionOperator(ExpressionType.ConvertChecked, expression, type, method); } ///.Type and .-or- .Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or- .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . Creates a ///that represents getting the length of a one-dimensional array. A ///Anthat has the property equal to and the property equal to . to set the property equal to. /// /// ///is null. /// public static UnaryExpression ArrayLength(Expression array) { ContractUtils.RequiresNotNull(array, "array"); if (!array.Type.IsArray || !typeof(Array).IsAssignableFrom(array.Type)) { throw Error.ArgumentMustBeArray(); } if (array.Type.GetArrayRank() != 1) { throw Error.ArgumentMustBeSingleDimensionalArrayType(); } return new UnaryExpression(ExpressionType.ArrayLength, array, typeof(int), null); } ///.Type does not represent an array type. Creates a ///that represents an expression that has a constant value of type . A ///Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// public static UnaryExpression Quote(Expression expression) { RequiresCanRead(expression, "expression"); if (!(expression is LambdaExpression)) throw Error.QuotedExpressionMustBeLambda(); return new UnaryExpression(ExpressionType.Quote, expression, expression.GetType(), null); } ///is null. /// Creates a ///that represents a rethrowing of an exception. /// A public static UnaryExpression Rethrow() { return Throw(null); } ///that represents a rethrowing of an exception. /// Creates a ///The newthat represents a rethrowing of an exception with a given type. /// of the expression. /// A public static UnaryExpression Rethrow(Type type) { return Throw(null, type); } ///that represents a rethrowing of an exception. /// Creates a /// Anthat represents a throwing of an exception. /// . /// A public static UnaryExpression Throw(Expression value) { return Throw(value, typeof(void)); } ///that represents the exception. /// Creates a /// Anthat represents a throwing of a value with a given type. /// . /// The new of the expression. /// A public static UnaryExpression Throw(Expression value, Type type) { ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (value != null) { RequiresCanRead(value, "value"); if (value.Type.IsValueType) throw Error.ArgumentMustNotHaveValueType(); } return new UnaryExpression(ExpressionType.Throw, value, type, null); } ///that represents the exception. /// Creates a /// Anthat represents the incrementing of the expression by 1. /// to increment. /// A public static UnaryExpression Increment(Expression expression) { return Increment(expression, null); } ///that represents the incremented expression. /// Creates a /// Anthat represents the incrementing of the expression by 1. /// to increment. ///A that represents the implementing method. /// A public static UnaryExpression Increment(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.Increment, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Increment, "op_Increment", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Increment, expression, method); } ///that represents the incremented expression. /// Creates a /// Anthat represents the decrementing of the expression by 1. /// to decrement. /// A public static UnaryExpression Decrement(Expression expression) { return Decrement(expression, null); } ///that represents the decremented expression. /// Creates a /// Anthat represents the decrementing of the expression by 1. /// to decrement. ///A that represents the implementing method. /// A public static UnaryExpression Decrement(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.Decrement, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Decrement, "op_Decrement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Decrement, expression, method); } ///that represents the decremented expression. /// Creates a /// Anthat increments the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A public static UnaryExpression PreIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat increments the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PreIncrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat decrements the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A public static UnaryExpression PreDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat decrements the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PreDecrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent increment by 1 of the original expression. /// to apply the operations on. /// A public static UnaryExpression PostIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent increment by 1 of the original expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PostIncrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent decrement by 1 of the original expression. /// to apply the operations on. /// A public static UnaryExpression PostDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent decrement by 1 of the original expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PostDecrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, method); } private static UnaryExpression MakeOpAssignUnary(ExpressionType kind, Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); RequiresCanWrite(expression, "expression"); UnaryExpression result; if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(kind, expression, expression.Type, null); } string name; if (kind == ExpressionType.PreIncrementAssign || kind == ExpressionType.PostIncrementAssign) { name = "op_Increment"; } else { name = "op_Decrement"; } result = GetUserDefinedUnaryOperatorOrThrow(kind, name, expression); } else { result = GetMethodBasedUnaryOperator(kind, expression, method); } // return type must be assignable back to the operand type if (!TypeUtils.AreReferenceAssignable(expression.Type, result.Type)) { throw Error.UserDefinedOpMustHaveValidReturnType(kind, method.Name); } return result; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Diagnostics; using System.Dynamic.Utils; using System.Reflection; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ///that represents the resultant expression. /// Represents an expression that has a unary operator. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.UnaryExpressionProxy))] #endif public sealed class UnaryExpression : Expression { private readonly Expression _operand; private readonly MethodInfo _method; private readonly ExpressionType _nodeType; private readonly Type _type; internal UnaryExpression(ExpressionType nodeType, Expression expression, Type type, MethodInfo method) { _operand = expression; _method = method; _nodeType = nodeType; _type = type; } ////// Gets the static type of the expression that this ///represents. (Inherited from .) /// The public sealed override Type Type { get { return _type; } } ///that represents the static type of the expression. /// Returns the node type of this ///. (Inherited from .) /// The public sealed override ExpressionType NodeType { get { return _nodeType; } } ///that represents this expression. /// Gets the operand of the unary operation. /// ///An public Expression Operand { get { return _operand; } } ///that represents the operand of the unary operation. /// Gets the implementing method for the unary operation. /// ///The public MethodInfo Method { get { return _method; } } ///that represents the implementing method. /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator. /// ///true if the node represents a lifted call; otherwise, false. public bool IsLifted { get { if (NodeType == ExpressionType.TypeAs || NodeType == ExpressionType.Quote || NodeType == ExpressionType.Throw) { return false; } bool operandIsNullable = TypeUtils.IsNullableType(_operand.Type); bool resultIsNullable = TypeUtils.IsNullableType(this.Type); if (_method != null) { return (operandIsNullable && !TypeUtils.AreEquivalent(_method.GetParametersCached()[0].ParameterType, _operand.Type)) || (resultIsNullable && !TypeUtils.AreEquivalent(_method.ReturnType, this.Type)); } return operandIsNullable || resultIsNullable; } } ////// Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type. /// ///true if the operator's return type is lifted to a nullable type; otherwise, false. public bool IsLiftedToNull { get { return IsLifted && TypeUtils.IsNullableType(this.Type); } } ////// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitUnary(this); } ////// Gets a value that indicates whether the expression tree node can be reduced. /// public override bool CanReduce { get { switch (_nodeType) { case ExpressionType.PreIncrementAssign: case ExpressionType.PreDecrementAssign: case ExpressionType.PostIncrementAssign: case ExpressionType.PostDecrementAssign: return true; } return false; } } ////// Reduces the expression node to a simpler expression. /// If CanReduce returns true, this should return a valid expression. /// This method is allowed to return another node which itself /// must be reduced. /// ///The reduced expression. public override Expression Reduce() { if (CanReduce) { switch (_operand.NodeType) { case ExpressionType.Index: return ReduceIndex(); case ExpressionType.MemberAccess: return ReduceMember(); default: return ReduceVariable(); } } return this; } private bool IsPrefix { get { return _nodeType == ExpressionType.PreIncrementAssign || _nodeType == ExpressionType.PreDecrementAssign; } } private UnaryExpression FunctionalOp(Expression operand) { ExpressionType functional; if (_nodeType == ExpressionType.PreIncrementAssign || _nodeType == ExpressionType.PostIncrementAssign) { functional = ExpressionType.Increment; } else { functional = ExpressionType.Decrement; } return new UnaryExpression(functional, operand, operand.Type, _method); } private Expression ReduceVariable() { if (IsPrefix) { // (op) var // ... is reduced into ... // var = op(var) return Assign(_operand, FunctionalOp(_operand)); } // var (op) // ... is reduced into ... // temp = var // var = op(var) // temp var temp = Parameter(_operand.Type, null); return Block( new[] { temp }, Assign(temp, _operand), Assign(_operand, FunctionalOp(temp)), temp ); } private Expression ReduceMember() { var member = (MemberExpression)_operand; if (member.Expression == null) { //static member, reduce the same as variable return ReduceVariable(); } else { var temp1 = Parameter(member.Expression.Type, null); var initTemp1 = Assign(temp1, member.Expression); member = MakeMemberAccess(temp1, member.Member); if (IsPrefix) { // (op) value.member // ... is reduced into ... // temp1 = value // temp1.member = op(temp1.member) return Block( new[] { temp1 }, initTemp1, Assign(member, FunctionalOp(member)) ); } // value.member (op) // ... is reduced into ... // temp1 = value // temp2 = temp1.member // temp1.member = op(temp2) // temp2 var temp2 = Parameter(member.Type, null); return Block( new[] { temp1, temp2 }, initTemp1, Assign(temp2, member), Assign(member, FunctionalOp(temp2)), temp2 ); } } private Expression ReduceIndex() { // left[a0, a1, ... aN] (op) // // ... is reduced into ... // // tempObj = left // tempArg0 = a0 // ... // tempArgN = aN // tempValue = tempObj[tempArg0, ... tempArgN] // tempObj[tempArg0, ... tempArgN] = op(tempValue) // tempValue bool prefix = IsPrefix; var index = (IndexExpression)_operand; int count = index.Arguments.Count; var block = new Expression[count + (prefix ? 2 : 4)]; var temps = new ParameterExpression[count + (prefix ? 1 : 2)]; var args = new ParameterExpression[count]; int i = 0; temps[i] = Parameter(index.Object.Type, null); block[i] = Assign(temps[i], index.Object); i++; while (i <= count) { var arg = index.Arguments[i - 1]; args[i - 1] = temps[i] = Parameter(arg.Type, null); block[i] = Assign(temps[i], arg); i++; } index = MakeIndex(temps[0], index.Indexer, new TrueReadOnlyCollection(args)); if (!prefix) { var lastTemp = temps[i] = Parameter(index.Type, null); block[i] = Assign(temps[i], index); i++; Debug.Assert(i == temps.Length); block[i++] = Assign(index, FunctionalOp(lastTemp)); block[i++] = lastTemp; } else { Debug.Assert(i == temps.Length); block[i++] = Assign(index, FunctionalOp(index)); } Debug.Assert(i == block.Length); return Block(new TrueReadOnlyCollection (temps), new TrueReadOnlyCollection (block)); } /// /// 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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public UnaryExpression Update(Expression operand) { if (operand == Operand) { return this; } return Expression.MakeUnary(NodeType, operand, Type, Method); } } public partial class Expression { ////// Creates a /// The, given an operand, by calling the appropriate factory method. /// that specifies the type of unary operation. /// An that represents the operand. /// The that specifies the type to be converted to (pass null if not applicable). /// The ///that results from calling the appropriate factory method. Thrown when ///does not correspond to a unary expression. Thrown when public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type) { return MakeUnary(unaryType, operand, type, null); } ///is null. /// Creates a /// The, given an operand and implementing method, by calling the appropriate factory method. /// that specifies the type of unary operation. /// An that represents the operand. /// The that specifies the type to be converted to (pass null if not applicable). /// The that represents the implementing method. /// The ///that results from calling the appropriate factory method. Thrown when ///does not correspond to a unary expression. Thrown when [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type, MethodInfo method) { switch (unaryType) { case ExpressionType.Negate: return Negate(operand, method); case ExpressionType.NegateChecked: return NegateChecked(operand, method); case ExpressionType.Not: return Not(operand, method); case ExpressionType.IsFalse: return IsFalse(operand, method); case ExpressionType.IsTrue: return IsTrue(operand, method); case ExpressionType.OnesComplement: return OnesComplement(operand, method); case ExpressionType.ArrayLength: return ArrayLength(operand); case ExpressionType.Convert: return Convert(operand, type, method); case ExpressionType.ConvertChecked: return ConvertChecked(operand, type, method); case ExpressionType.Throw: return Throw(operand, type); case ExpressionType.TypeAs: return TypeAs(operand, type); case ExpressionType.Quote: return Quote(operand); case ExpressionType.UnaryPlus: return UnaryPlus(operand, method); case ExpressionType.Unbox: return Unbox(operand, type); case ExpressionType.Increment: return Increment(operand, method); case ExpressionType.Decrement: return Decrement(operand, method); case ExpressionType.PreIncrementAssign: return PreIncrementAssign(operand, method); case ExpressionType.PostIncrementAssign: return PostIncrementAssign(operand, method); case ExpressionType.PreDecrementAssign: return PreDecrementAssign(operand, method); case ExpressionType.PostDecrementAssign: return PostDecrementAssign(operand, method); default: throw Error.UnhandledUnary(unaryType); } } private static UnaryExpression GetUserDefinedUnaryOperatorOrThrow(ExpressionType unaryType, string name, Expression operand) { UnaryExpression u = GetUserDefinedUnaryOperator(unaryType, name, operand); if (u != null) { ValidateParamswithOperandsOrThrow(u.Method.GetParametersCached()[0].ParameterType, operand.Type, unaryType, name); return u; } throw Error.UnaryOperatorNotDefined(unaryType, operand.Type); } private static UnaryExpression GetUserDefinedUnaryOperator(ExpressionType unaryType, string name, Expression operand) { Type operandType = operand.Type; Type[] types = new Type[] { operandType }; Type nnOperandType = TypeUtils.GetNonNullableType(operandType); BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = nnOperandType.GetMethodValidated(name, flags, null, types, null); if (method != null) { return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // try lifted call if (TypeUtils.IsNullableType(operandType)) { types[0] = nnOperandType; method = nnOperandType.GetMethodValidated(name, flags, null, types, null); if (method != null && method.ReturnType.IsValueType && !TypeUtils.IsNullableType(method.ReturnType)) { return new UnaryExpression(unaryType, operand, TypeUtils.GetNullableType(method.ReturnType), method); } } return null; } private static UnaryExpression GetMethodBasedUnaryOperator(ExpressionType unaryType, Expression operand, MethodInfo method) { System.Diagnostics.Debug.Assert(method != null); ValidateOperator(method); ParameterInfo[] pms = method.GetParametersCached(); if (pms.Length != 1) throw Error.IncorrectNumberOfMethodCallArguments(method); if (ParameterIsAssignable(pms[0], operand.Type)) { ValidateParamswithOperandsOrThrow(pms[0].ParameterType, operand.Type, unaryType, method.Name); return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // check for lifted call if (TypeUtils.IsNullableType(operand.Type) && ParameterIsAssignable(pms[0], TypeUtils.GetNonNullableType(operand.Type)) && method.ReturnType.IsValueType && !TypeUtils.IsNullableType(method.ReturnType)) { return new UnaryExpression(unaryType, operand, TypeUtils.GetNullableType(method.ReturnType), method); } throw Error.OperandTypesDoNotMatchParameters(unaryType, method.Name); } private static UnaryExpression GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType) { UnaryExpression u = GetUserDefinedCoercion(coercionType, expression, convertToType); if (u != null) { return u; } throw Error.CoercionOperatorNotDefined(expression.Type, convertToType); } private static UnaryExpression GetUserDefinedCoercion(ExpressionType coercionType, Expression expression, Type convertToType) { MethodInfo method = TypeUtils.GetUserDefinedCoercionMethod(expression.Type, convertToType, false); if (method != null) { return new UnaryExpression(coercionType, expression, convertToType, method); } else { return null; } } private static UnaryExpression GetMethodBasedCoercionOperator(ExpressionType unaryType, Expression operand, Type convertToType, MethodInfo method) { System.Diagnostics.Debug.Assert(method != null); ValidateOperator(method); ParameterInfo[] pms = method.GetParametersCached(); if (pms.Length != 1) { throw Error.IncorrectNumberOfMethodCallArguments(method); } if (ParameterIsAssignable(pms[0], operand.Type) && TypeUtils.AreEquivalent(method.ReturnType, convertToType)) { return new UnaryExpression(unaryType, operand, method.ReturnType, method); } // check for lifted call if ((TypeUtils.IsNullableType(operand.Type) || TypeUtils.IsNullableType(convertToType)) && ParameterIsAssignable(pms[0], TypeUtils.GetNonNullableType(operand.Type)) && TypeUtils.AreEquivalent(method.ReturnType, TypeUtils.GetNonNullableType(convertToType))) { return new UnaryExpression(unaryType, operand, convertToType, method); } throw Error.OperandTypesDoNotMatchParameters(unaryType, method.Name); } ///is null. /// Creates a /// Anthat represents an arithmetic negation operation. /// to set the property equal to. /// A ///that has the property equal to and the properties set to the specified value. Thrown when ///is null. Thrown when the unary minus operator is not defined for public static UnaryExpression Negate(Expression expression) { return Negate(expression, null); } ////// Creates a /// Anthat represents an arithmetic negation operation. /// to set the property equal to. /// A to set the property equal to. /// A ///that has the property equal to and the and properties set to the specified value. Thrown when ///is null. Thrown when ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. Thown when public static UnaryExpression Negate(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type) && !TypeUtils.IsUnsignedInt(expression.Type)) { return new UnaryExpression(ExpressionType.Negate, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Negate, "op_UnaryNegation", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Negate, expression, method); } ///is null and the unary minus operator is not defined for expression.Type or expression.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. /// Creates a /// Anthat represents a unary plus operation. /// to set the property equal to. /// A ///that has the property equal to and the property set to the specified value. Thrown when ///is null. Thown when the unary minus operator is not defined for expression.Type. public static UnaryExpression UnaryPlus(Expression expression) { return UnaryPlus(expression, null); } ////// Creates a /// Anthat represents a unary plus operation. /// to set the property equal to. /// A to set the property equal to. /// A ///that has the property equal to and the and property set to the specified value. Thrown when ///is null. Thrown when ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. Thown when public static UnaryExpression UnaryPlus(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.UnaryPlus, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.UnaryPlus, "op_UnaryPlus", expression); } return GetMethodBasedUnaryOperator(ExpressionType.UnaryPlus, expression, method); } ///is null and the unary minus operator is not defined for expression.Type or expression.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. Creates a ///that represents an arithmetic negation operation that has overflow checking. A /// Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// Thrown when ///is null. Thrown when the unary minus operator is not defined for public static UnaryExpression NegateChecked(Expression expression) { return NegateChecked(expression, null); } ///.Type. Creates a ///that represents an arithmetic negation operation that has overflow checking. The implementing method can be specified. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. /// public static UnaryExpression NegateChecked(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type) && !TypeUtils.IsUnsignedInt(expression.Type)) { return new UnaryExpression(ExpressionType.NegateChecked, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.NegateChecked, "op_UnaryNegation", expression); } return GetMethodBasedUnaryOperator(ExpressionType.NegateChecked, expression, method); } ///is null and the unary minus operator is not defined for .Type.-or- .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . Creates a ///that represents a bitwise complement operation. A ///Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// ///is null. The unary not operator is not defined for public static UnaryExpression Not(Expression expression) { return Not(expression, null); } ///.Type. Creates a ///that represents a bitwise complement operation. The implementing method can be specified. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. /// public static UnaryExpression Not(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsIntegerOrBool(expression.Type)) { return new UnaryExpression(ExpressionType.Not, expression, expression.Type, null); } UnaryExpression u = GetUserDefinedUnaryOperator(ExpressionType.Not, "op_LogicalNot", expression); if (u != null) { return u; } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Not, "op_OnesComplement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Not, expression, method); } ///is null and the unary not operator is not defined for .Type.-or- .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . /// Returns whether the expression evaluates to false. /// /// Anto evaluate. /// An instance of public static UnaryExpression IsFalse(Expression expression) { return IsFalse(expression, null); } ///. /// Returns whether the expression evaluates to false. /// ///Anto evaluate. ///A that represents the implementing method. /// An instance of public static UnaryExpression IsFalse(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsBool(expression.Type)) { return new UnaryExpression(ExpressionType.IsFalse, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.IsFalse, "op_False", expression); } return GetMethodBasedUnaryOperator(ExpressionType.IsFalse, expression, method); } ///. /// Returns whether the expression evaluates to true. /// /// Anto evaluate. /// An instance of public static UnaryExpression IsTrue(Expression expression) { return IsTrue(expression, null); } ///. /// Returns whether the expression evaluates to true. /// ///Anto evaluate. ///A that represents the implementing method. /// An instance of public static UnaryExpression IsTrue(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsBool(expression.Type)) { return new UnaryExpression(ExpressionType.IsTrue, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.IsTrue, "op_True", expression); } return GetMethodBasedUnaryOperator(ExpressionType.IsTrue, expression, method); } ///. /// Returns the expression representing the ones complement. /// ///An. /// An instance of public static UnaryExpression OnesComplement(Expression expression) { return OnesComplement(expression, null); } ///. /// Returns the expression representing the ones complement. /// /// An. /// A that represents the implementing method. /// An instance of public static UnaryExpression OnesComplement(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsInteger(expression.Type)) { return new UnaryExpression(ExpressionType.OnesComplement, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.OnesComplement, "op_OnesComplement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.OnesComplement, expression, method); } ///. Creates a ///that represents an explicit reference or boxing conversion where null is supplied if the conversion fails. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// public static UnaryExpression TypeAs(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (type.IsValueType && !TypeUtils.IsNullableType(type)) { throw Error.IncorrectTypeForTypeAs(type); } return new UnaryExpression(ExpressionType.TypeAs, expression, type, null); } ///or is null. /// /// AnCreates a ///that represents an explicit unboxing. to unbox. /// The new of the expression. /// An instance of public static UnaryExpression Unbox(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (!expression.Type.IsInterface && expression.Type != typeof(object)) { throw Error.InvalidUnboxType(); } if (!type.IsValueType) throw Error.InvalidUnboxType(); TypeUtils.ValidateType(type); return new UnaryExpression(ExpressionType.Unbox, expression, type, null); } ///. Creates a ///that represents a conversion operation. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///or is null. No conversion operator is defined between public static UnaryExpression Convert(Expression expression, Type type) { return Convert(expression, type, null); } ///.Type and . Creates a ///that represents a conversion operation for which the implementing method is specified. A ///Anthat has the property equal to and the , , and properties set to the specified values. to set the property equal to. ///A to set the property equal to. ///A to set the property equal to. /// /// ///or is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. More than one method that matches the ///description was found. No conversion operator is defined between public static UnaryExpression Convert(Expression expression, Type type, MethodInfo method) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (method == null) { if (TypeUtils.HasIdentityPrimitiveOrNullableConversion(expression.Type, type) || TypeUtils.HasReferenceConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.Convert, expression, type, null); } return GetUserDefinedCoercionOrThrow(ExpressionType.Convert, expression, type); } return GetMethodBasedCoercionOperator(ExpressionType.Convert, expression, type, method); } ///.Type and .-or- .Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or- .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . Creates a ///that represents a conversion operation that throws an exception if the target type is overflowed. A ///Anthat has the property equal to and the and properties set to the specified values. to set the property equal to. ///A to set the property equal to. /// /// ///or is null. No conversion operator is defined between public static UnaryExpression ConvertChecked(Expression expression, Type type) { return ConvertChecked(expression, type, null); } ///.Type and . Creates a ///that represents a conversion operation that throws an exception if the target type is overflowed and for which the implementing method is specified. A ///Anthat has the property equal to and the , , and properties set to the specified values. to set the property equal to. ///A to set the property equal to. ///A to set the property equal to. /// /// ///or is null. /// ///is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. More than one method that matches the ///description was found. No conversion operator is defined between public static UnaryExpression ConvertChecked(Expression expression, Type type, MethodInfo method) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (method == null) { if (TypeUtils.HasIdentityPrimitiveOrNullableConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.ConvertChecked, expression, type, null); } if (TypeUtils.HasReferenceConversion(expression.Type, type)) { return new UnaryExpression(ExpressionType.Convert, expression, type, null); } return GetUserDefinedCoercionOrThrow(ExpressionType.ConvertChecked, expression, type); } return GetMethodBasedCoercionOperator(ExpressionType.ConvertChecked, expression, type, method); } ///.Type and .-or- .Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or- .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . Creates a ///that represents getting the length of a one-dimensional array. A ///Anthat has the property equal to and the property equal to . to set the property equal to. /// /// ///is null. /// public static UnaryExpression ArrayLength(Expression array) { ContractUtils.RequiresNotNull(array, "array"); if (!array.Type.IsArray || !typeof(Array).IsAssignableFrom(array.Type)) { throw Error.ArgumentMustBeArray(); } if (array.Type.GetArrayRank() != 1) { throw Error.ArgumentMustBeSingleDimensionalArrayType(); } return new UnaryExpression(ExpressionType.ArrayLength, array, typeof(int), null); } ///.Type does not represent an array type. Creates a ///that represents an expression that has a constant value of type . A ///Anthat has the property equal to and the property set to the specified value. to set the property equal to. /// /// public static UnaryExpression Quote(Expression expression) { RequiresCanRead(expression, "expression"); if (!(expression is LambdaExpression)) throw Error.QuotedExpressionMustBeLambda(); return new UnaryExpression(ExpressionType.Quote, expression, expression.GetType(), null); } ///is null. /// Creates a ///that represents a rethrowing of an exception. /// A public static UnaryExpression Rethrow() { return Throw(null); } ///that represents a rethrowing of an exception. /// Creates a ///The newthat represents a rethrowing of an exception with a given type. /// of the expression. /// A public static UnaryExpression Rethrow(Type type) { return Throw(null, type); } ///that represents a rethrowing of an exception. /// Creates a /// Anthat represents a throwing of an exception. /// . /// A public static UnaryExpression Throw(Expression value) { return Throw(value, typeof(void)); } ///that represents the exception. /// Creates a /// Anthat represents a throwing of a value with a given type. /// . /// The new of the expression. /// A public static UnaryExpression Throw(Expression value, Type type) { ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (value != null) { RequiresCanRead(value, "value"); if (value.Type.IsValueType) throw Error.ArgumentMustNotHaveValueType(); } return new UnaryExpression(ExpressionType.Throw, value, type, null); } ///that represents the exception. /// Creates a /// Anthat represents the incrementing of the expression by 1. /// to increment. /// A public static UnaryExpression Increment(Expression expression) { return Increment(expression, null); } ///that represents the incremented expression. /// Creates a /// Anthat represents the incrementing of the expression by 1. /// to increment. ///A that represents the implementing method. /// A public static UnaryExpression Increment(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.Increment, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Increment, "op_Increment", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Increment, expression, method); } ///that represents the incremented expression. /// Creates a /// Anthat represents the decrementing of the expression by 1. /// to decrement. /// A public static UnaryExpression Decrement(Expression expression) { return Decrement(expression, null); } ///that represents the decremented expression. /// Creates a /// Anthat represents the decrementing of the expression by 1. /// to decrement. ///A that represents the implementing method. /// A public static UnaryExpression Decrement(Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(ExpressionType.Decrement, expression, expression.Type, null); } return GetUserDefinedUnaryOperatorOrThrow(ExpressionType.Decrement, "op_Decrement", expression); } return GetMethodBasedUnaryOperator(ExpressionType.Decrement, expression, method); } ///that represents the decremented expression. /// Creates a /// Anthat increments the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A public static UnaryExpression PreIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat increments the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PreIncrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat decrements the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A public static UnaryExpression PreDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat decrements the expression by 1 /// and assigns the result back to the expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PreDecrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent increment by 1 of the original expression. /// to apply the operations on. /// A public static UnaryExpression PostIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent increment by 1 of the original expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PostIncrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, method); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent decrement by 1 of the original expression. /// to apply the operations on. /// A public static UnaryExpression PostDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, null); } ///that represents the resultant expression. /// Creates a /// Anthat represents the assignment of the expression /// followed by a subsequent decrement by 1 of the original expression. /// to apply the operations on. /// A that represents the implementing method. /// A public static UnaryExpression PostDecrementAssign(Expression expression, MethodInfo method) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, method); } private static UnaryExpression MakeOpAssignUnary(ExpressionType kind, Expression expression, MethodInfo method) { RequiresCanRead(expression, "expression"); RequiresCanWrite(expression, "expression"); UnaryExpression result; if (method == null) { if (TypeUtils.IsArithmetic(expression.Type)) { return new UnaryExpression(kind, expression, expression.Type, null); } string name; if (kind == ExpressionType.PreIncrementAssign || kind == ExpressionType.PostIncrementAssign) { name = "op_Increment"; } else { name = "op_Decrement"; } result = GetUserDefinedUnaryOperatorOrThrow(kind, name, expression); } else { result = GetMethodBasedUnaryOperator(kind, expression, method); } // return type must be assignable back to the operand type if (!TypeUtils.AreReferenceAssignable(expression.Type, result.Type)) { throw Error.UserDefinedOpMustHaveValidReturnType(kind, method.Name); } return result; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.that represents the resultant expression.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PreProcessor.cs
- EntityClassGenerator.cs
- XmlWriterSettings.cs
- EntityDataSource.cs
- AutomationAttributeInfo.cs
- GradientSpreadMethodValidation.cs
- ViewCellSlot.cs
- ValueSerializerAttribute.cs
- EventDescriptorCollection.cs
- HyperLinkField.cs
- ComNativeDescriptor.cs
- VirtualDirectoryMappingCollection.cs
- WebBrowserBase.cs
- SelectionItemProviderWrapper.cs
- TypeRefElement.cs
- FixedElement.cs
- StrokeRenderer.cs
- DBPropSet.cs
- objectresult_tresulttype.cs
- CategoryGridEntry.cs
- SqlTypesSchemaImporter.cs
- DataViewManager.cs
- HwndTarget.cs
- RemoteWebConfigurationHostStream.cs
- FontWeightConverter.cs
- WebBrowserDocumentCompletedEventHandler.cs
- QueryStringParameter.cs
- ScriptControl.cs
- DirectoryRootQuery.cs
- Decoder.cs
- RectValueSerializer.cs
- FlowNode.cs
- DocumentOrderQuery.cs
- ReadingWritingEntityEventArgs.cs
- DataErrorValidationRule.cs
- _HTTPDateParse.cs
- IdleTimeoutMonitor.cs
- WebPartConnectionsConnectVerb.cs
- Latin1Encoding.cs
- QilTypeChecker.cs
- OrderPreservingMergeHelper.cs
- FieldBuilder.cs
- OracleDataReader.cs
- DataServiceExpressionVisitor.cs
- ProfileProvider.cs
- SqlRemoveConstantOrderBy.cs
- MarkupCompiler.cs
- XPathNodeHelper.cs
- Track.cs
- SingleAnimation.cs
- InputMethod.cs
- IPPacketInformation.cs
- Win32Exception.cs
- Vector.cs
- HybridWebProxyFinder.cs
- TemplateBindingExtensionConverter.cs
- TreeNode.cs
- ResponseBodyWriter.cs
- SystemWebCachingSectionGroup.cs
- SBCSCodePageEncoding.cs
- QueryCacheManager.cs
- UInt16Storage.cs
- RepeaterDesigner.cs
- BasicExpandProvider.cs
- XPathNavigatorKeyComparer.cs
- SemanticResultValue.cs
- WSDualHttpBindingElement.cs
- SizeConverter.cs
- SharedPersonalizationStateInfo.cs
- XmlSchemaInfo.cs
- Compilation.cs
- XmlDictionaryReaderQuotas.cs
- TextSchema.cs
- CellCreator.cs
- DataBinder.cs
- HashAlgorithm.cs
- CleanUpVirtualizedItemEventArgs.cs
- ServicePointManagerElement.cs
- coordinatorscratchpad.cs
- TimeSpanValidator.cs
- _UncName.cs
- ConsoleCancelEventArgs.cs
- SharedStream.cs
- SqlMethodCallConverter.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- ToolStripComboBox.cs
- _HelperAsyncResults.cs
- ResourcePool.cs
- BackEase.cs
- StorageFunctionMapping.cs
- ToggleButtonAutomationPeer.cs
- SecUtil.cs
- ServicePointManager.cs
- FilterQuery.cs
- ScriptResourceHandler.cs
- XamlReaderHelper.cs
- RadioButton.cs
- HybridDictionary.cs
- BamlWriter.cs
- MD5.cs