Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Ast / TypeBinaryExpression.cs / 1305376 / TypeBinaryExpression.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; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ////// Represents an operation between an expression and a type. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.TypeBinaryExpressionProxy))] #endif public sealed class TypeBinaryExpression : Expression { private readonly Expression _expression; private readonly Type _typeOperand; private readonly ExpressionType _nodeKind; internal TypeBinaryExpression(Expression expression, Type typeOperand, ExpressionType nodeKind) { _expression = expression; _typeOperand = typeOperand; _nodeKind = nodeKind; } ////// Gets the static type of the expression that this ///represents. /// The public sealed override Type Type { get { return typeof(bool); } } ///that represents the static type of the expression. /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// ///The public sealed override ExpressionType NodeType { get { return _nodeKind; } } ///of the expression. /// Gets the expression operand of a type test operation. /// public Expression Expression { get { return _expression; } } ////// Gets the type operand of a type test operation. /// public Type TypeOperand { get { return _typeOperand; } } #region Reduce TypeEqual internal Expression ReduceTypeEqual() { Type cType = Expression.Type; // For value types (including Void, but not nullables), we can // determine the result now if (cType.IsValueType && !cType.IsNullableType()) { return Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())); } // Can check the value right now for constants. if (Expression.NodeType == ExpressionType.Constant) { return ReduceConstantTypeEqual(); } // If the operand type is a sealed reference type or a nullable // type, it will match if value is not null if (cType.IsSealed && (cType == _typeOperand)) { if (cType.IsNullableType()) { return Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)); } else { return Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)); } } // expression is a ByVal parameter. Can safely reevaluate. var parameter = Expression as ParameterExpression; if (parameter != null && !parameter.IsByRef) { return ByValParameterTypeEqual(parameter); } // Create a temp so we only evaluate the left side once parameter = Expression.Parameter(typeof(object)); // Convert to object if necessary var expression = Expression; if (!TypeUtils.AreReferenceAssignable(typeof(object), expression.Type)) { expression = Expression.Convert(expression, typeof(object)); } return Expression.Block( new[] { parameter }, Expression.Assign(parameter, expression), ByValParameterTypeEqual(parameter) ); } // Helper that is used when re-eval of LHS is safe. private Expression ByValParameterTypeEqual(ParameterExpression value) { Expression getType = Expression.Call(value, typeof(object).GetMethod("GetType")); // In remoting scenarios, obj.GetType() can return an interface. // But there's a bug in the JIT32's optimized "obj.GetType() == // typeof(ISomething)" codegen, causing it to always return false. // We workaround the bug by generating different, less optimal IL // if TypeOperand is an interface. if (_typeOperand.IsInterface) { var temp = Expression.Parameter(typeof(Type)); getType = Expression.Block(new[] { temp }, Expression.Assign(temp, getType), temp); } // We use reference equality when comparing to null for correctness // (don't invoke a user defined operator), and reference equality // on types for performance (so the JIT can optimize the IL). return Expression.AndAlso( Expression.ReferenceNotEqual(value, Expression.Constant(null)), Expression.ReferenceEqual( getType, Expression.Constant(_typeOperand.GetNonNullableType(), typeof(Type)) ) ); } private Expression ReduceConstantTypeEqual() { ConstantExpression ce = Expression as ConstantExpression; //TypeEqual(null, T) always returns false. if (ce.Value == null) { return Expression.Constant(false); } else { return Expression.Constant(_typeOperand.GetNonNullableType() == ce.Value.GetType()); } } #endregion ////// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitTypeBinary(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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public TypeBinaryExpression Update(Expression expression) { if (expression == Expression) { return this; } if (NodeType == ExpressionType.TypeIs) { return Expression.TypeIs(expression, TypeOperand); } return Expression.TypeEqual(expression, TypeOperand); } } public partial class Expression { ////// Creates a /// An. /// to set the property equal to. /// A to set the property equal to. /// A public static TypeBinaryExpression TypeIs(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (type.IsByRef) throw Error.TypeMustNotBeByRef(); return new TypeBinaryExpression(expression, type, ExpressionType.TypeIs); } ///for which the property is equal to and for which the and properties are set to the specified values. /// Creates a /// Anthat compares run-time type identity. /// to set the property equal to. /// A to set the property equal to. /// A public static TypeBinaryExpression TypeEqual(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (type.IsByRef) throw Error.TypeMustNotBeByRef(); return new TypeBinaryExpression(expression, type, ExpressionType.TypeEqual); } } } // 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; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ///for which the property is equal to and for which the and properties are set to the specified values. /// Represents an operation between an expression and a type. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.TypeBinaryExpressionProxy))] #endif public sealed class TypeBinaryExpression : Expression { private readonly Expression _expression; private readonly Type _typeOperand; private readonly ExpressionType _nodeKind; internal TypeBinaryExpression(Expression expression, Type typeOperand, ExpressionType nodeKind) { _expression = expression; _typeOperand = typeOperand; _nodeKind = nodeKind; } ////// Gets the static type of the expression that this ///represents. /// The public sealed override Type Type { get { return typeof(bool); } } ///that represents the static type of the expression. /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// ///The public sealed override ExpressionType NodeType { get { return _nodeKind; } } ///of the expression. /// Gets the expression operand of a type test operation. /// public Expression Expression { get { return _expression; } } ////// Gets the type operand of a type test operation. /// public Type TypeOperand { get { return _typeOperand; } } #region Reduce TypeEqual internal Expression ReduceTypeEqual() { Type cType = Expression.Type; // For value types (including Void, but not nullables), we can // determine the result now if (cType.IsValueType && !cType.IsNullableType()) { return Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())); } // Can check the value right now for constants. if (Expression.NodeType == ExpressionType.Constant) { return ReduceConstantTypeEqual(); } // If the operand type is a sealed reference type or a nullable // type, it will match if value is not null if (cType.IsSealed && (cType == _typeOperand)) { if (cType.IsNullableType()) { return Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)); } else { return Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)); } } // expression is a ByVal parameter. Can safely reevaluate. var parameter = Expression as ParameterExpression; if (parameter != null && !parameter.IsByRef) { return ByValParameterTypeEqual(parameter); } // Create a temp so we only evaluate the left side once parameter = Expression.Parameter(typeof(object)); // Convert to object if necessary var expression = Expression; if (!TypeUtils.AreReferenceAssignable(typeof(object), expression.Type)) { expression = Expression.Convert(expression, typeof(object)); } return Expression.Block( new[] { parameter }, Expression.Assign(parameter, expression), ByValParameterTypeEqual(parameter) ); } // Helper that is used when re-eval of LHS is safe. private Expression ByValParameterTypeEqual(ParameterExpression value) { Expression getType = Expression.Call(value, typeof(object).GetMethod("GetType")); // In remoting scenarios, obj.GetType() can return an interface. // But there's a bug in the JIT32's optimized "obj.GetType() == // typeof(ISomething)" codegen, causing it to always return false. // We workaround the bug by generating different, less optimal IL // if TypeOperand is an interface. if (_typeOperand.IsInterface) { var temp = Expression.Parameter(typeof(Type)); getType = Expression.Block(new[] { temp }, Expression.Assign(temp, getType), temp); } // We use reference equality when comparing to null for correctness // (don't invoke a user defined operator), and reference equality // on types for performance (so the JIT can optimize the IL). return Expression.AndAlso( Expression.ReferenceNotEqual(value, Expression.Constant(null)), Expression.ReferenceEqual( getType, Expression.Constant(_typeOperand.GetNonNullableType(), typeof(Type)) ) ); } private Expression ReduceConstantTypeEqual() { ConstantExpression ce = Expression as ConstantExpression; //TypeEqual(null, T) always returns false. if (ce.Value == null) { return Expression.Constant(false); } else { return Expression.Constant(_typeOperand.GetNonNullableType() == ce.Value.GetType()); } } #endregion ////// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitTypeBinary(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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public TypeBinaryExpression Update(Expression expression) { if (expression == Expression) { return this; } if (NodeType == ExpressionType.TypeIs) { return Expression.TypeIs(expression, TypeOperand); } return Expression.TypeEqual(expression, TypeOperand); } } public partial class Expression { ////// Creates a /// An. /// to set the property equal to. /// A to set the property equal to. /// A public static TypeBinaryExpression TypeIs(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (type.IsByRef) throw Error.TypeMustNotBeByRef(); return new TypeBinaryExpression(expression, type, ExpressionType.TypeIs); } ///for which the property is equal to and for which the and properties are set to the specified values. /// Creates a /// Anthat compares run-time type identity. /// to set the property equal to. /// A to set the property equal to. /// A public static TypeBinaryExpression TypeEqual(Expression expression, Type type) { RequiresCanRead(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); if (type.IsByRef) throw Error.TypeMustNotBeByRef(); return new TypeBinaryExpression(expression, type, ExpressionType.TypeEqual); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.for which the property is equal to and for which the and properties are set to the specified values.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ToolStripStatusLabel.cs
- InputLanguageSource.cs
- Style.cs
- PermissionSetEnumerator.cs
- RuleCache.cs
- AesManaged.cs
- RichTextBoxAutomationPeer.cs
- VersionedStreamOwner.cs
- WindowsStreamSecurityElement.cs
- ConfigPathUtility.cs
- FontResourceCache.cs
- SafeIUnknown.cs
- EventInfo.cs
- BitmapEffectState.cs
- CollectionEditVerbManager.cs
- CustomMenuItemCollection.cs
- EmbeddedMailObject.cs
- TransactionScope.cs
- BreadCrumbTextConverter.cs
- ManifestResourceInfo.cs
- SqlTrackingService.cs
- ToolStripPanel.cs
- SessionStateItemCollection.cs
- XmlSchemaSimpleContent.cs
- SequenceDesignerAccessibleObject.cs
- StrokeFIndices.cs
- AsymmetricSignatureDeformatter.cs
- ObjectDataSourceDisposingEventArgs.cs
- XmlSchemaSequence.cs
- ParamArrayAttribute.cs
- ObsoleteAttribute.cs
- SubMenuStyle.cs
- TextComposition.cs
- SystemIPGlobalProperties.cs
- ProcessInputEventArgs.cs
- ViewPort3D.cs
- Attribute.cs
- Expressions.cs
- UmAlQuraCalendar.cs
- RegexReplacement.cs
- IProvider.cs
- ExpressionBindingsDialog.cs
- MDIControlStrip.cs
- TemplateColumn.cs
- HttpPostLocalhostServerProtocol.cs
- FrameDimension.cs
- DropDownButton.cs
- IOException.cs
- WebPartChrome.cs
- CorrelationQueryBehavior.cs
- AppearanceEditorPart.cs
- DefaultWorkflowTransactionService.cs
- EmulateRecognizeCompletedEventArgs.cs
- Nullable.cs
- BindingBase.cs
- AnnotationAdorner.cs
- TransformGroup.cs
- DecimalConverter.cs
- ImageMapEventArgs.cs
- Size3D.cs
- SqlNodeTypeOperators.cs
- DesignerResources.cs
- AggregateNode.cs
- UnsafeNativeMethods.cs
- ComplusTypeValidator.cs
- xmlfixedPageInfo.cs
- HttpFileCollectionBase.cs
- WebPartTransformerCollection.cs
- X509SecurityToken.cs
- _ConnectOverlappedAsyncResult.cs
- GeneralTransform3DGroup.cs
- TimeStampChecker.cs
- DataPagerCommandEventArgs.cs
- TextOnlyOutput.cs
- ManagedIStream.cs
- Button.cs
- HiddenField.cs
- HtmlInputButton.cs
- Compiler.cs
- InvariantComparer.cs
- SmtpFailedRecipientsException.cs
- OneOfTypeConst.cs
- ConnectionsZone.cs
- DataGridViewSelectedRowCollection.cs
- Globals.cs
- SqlDataSource.cs
- HotSpotCollection.cs
- MissingFieldException.cs
- ExpressionDumper.cs
- ResponseStream.cs
- Shape.cs
- AffineTransform3D.cs
- DataGrid.cs
- BamlTreeNode.cs
- Matrix3DConverter.cs
- FontSourceCollection.cs
- ADConnectionHelper.cs
- ReflectionPermission.cs
- XmlSchemaAttribute.cs
- sortedlist.cs