Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Ast / IndexExpression.cs / 1305376 / IndexExpression.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.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ////// Represents indexing a property or array. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.IndexExpressionProxy))] #endif public sealed class IndexExpression : Expression, IArgumentProvider { private readonly Expression _instance; private readonly PropertyInfo _indexer; private IList_arguments; internal IndexExpression( Expression instance, PropertyInfo indexer, IList arguments) { if (indexer == null) { Debug.Assert(instance != null && instance.Type.IsArray); Debug.Assert(instance.Type.GetArrayRank() == arguments.Count); } _instance = instance; _indexer = indexer; _arguments = arguments; } /// /// Returns the node type of this ///. (Inherited from .) /// The public sealed override ExpressionType NodeType { get { return ExpressionType.Index; } } ///that represents this expression. /// Gets the static type of the expression that this ///represents. (Inherited from .) /// The public sealed override Type Type { get { if (_indexer != null) { return _indexer.PropertyType; } return _instance.Type.GetElementType(); } } ///that represents the static type of the expression. /// An object to index. /// public Expression Object { get { return _instance; } } ////// Gets the public PropertyInfo Indexer { get { return _indexer; } } ///for the property if the expression represents an indexed property, returns null otherwise. /// /// Gets the arguments to be used to index the property or array. /// public ReadOnlyCollectionArguments { get { return ReturnReadOnly(ref _arguments); } } /// /// 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. /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public IndexExpression Update(Expression @object, IEnumerablearguments) { if (@object == Object && arguments == Arguments) { return this; } return Expression.MakeIndex(@object, Indexer, arguments); } Expression IArgumentProvider.GetArgument(int index) { return _arguments[index]; } int IArgumentProvider.ArgumentCount { get { return _arguments.Count; } } /// /// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitIndex(this); } internal Expression Rewrite(Expression instance, Expression[] arguments) { Debug.Assert(instance != null); Debug.Assert(arguments == null || arguments.Length == _arguments.Count); return Expression.MakeIndex(instance, _indexer, arguments ?? _arguments); } } public partial class Expression { ////// Creates an /// The object to which the property belongs. Should be null if the property is static(shared). /// Anthat represents accessing an indexed property in an object. /// representing the property to index. /// An IEnumerable{Expression} contaning the arguments to be used to index the property. /// The created public static IndexExpression MakeIndex(Expression instance, PropertyInfo indexer, IEnumerable. arguments) { if (indexer != null) { return Property(instance, indexer, arguments); } else { return ArrayAccess(instance, arguments); } } #region ArrayAccess /// /// Creates an /// An expression representing the array to index. /// An array containing expressions used to index the array. ///to access an array. /// The expression representing the array can be obtained by using the MakeMemberAccess method, /// or through NewArrayBounds or NewArrayInit. ///The created public static IndexExpression ArrayAccess(Expression array, params Expression[] indexes) { return ArrayAccess(array, (IEnumerable. )indexes); } /// /// Creates an /// An expression representing the array to index. /// Anto access an array. /// containing expressions used to index the array. /// The expression representing the array can be obtained by using the MakeMemberAccess method, /// or through NewArrayBounds or NewArrayInit. ///The created public static IndexExpression ArrayAccess(Expression array, IEnumerable. indexes) { RequiresCanRead(array, "array"); Type arrayType = array.Type; if (!arrayType.IsArray) { throw Error.ArgumentMustBeArray(); } var indexList = indexes.ToReadOnly(); if (arrayType.GetArrayRank() != indexList.Count) { throw Error.IncorrectNumberOfIndexes(); } foreach (Expression e in indexList) { RequiresCanRead(e, "indexes"); if (e.Type != typeof(int)) { throw Error.ArgumentMustBeArrayIndexType(); } } return new IndexExpression(array, null, indexList); } #endregion #region Property /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// The name of the indexer. /// An array ofrepresenting the access to an indexed property. /// objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, string propertyName, params Expression[] arguments) { RequiresCanRead(instance, "instance"); ContractUtils.RequiresNotNull(propertyName, "indexerName"); PropertyInfo pi = FindInstanceProperty(instance.Type, propertyName, arguments); return Property(instance, pi, arguments); } #region methods for finding a PropertyInfo by its name ///. /// The method finds the instance property with the specified name in a type. The property's type signature needs to be compatible with /// the arguments if it is a indexer. If the arguments is null or empty, we get a normal property. /// private static PropertyInfo FindInstanceProperty(Type type, string propertyName, Expression[] arguments) { // bind to public names first BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy; PropertyInfo pi = FindProperty(type, propertyName, arguments, flags); if (pi == null) { flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy; pi = FindProperty(type, propertyName, arguments, flags); } if (pi == null) { if (arguments == null || arguments.Length == 0) { throw Error.InstancePropertyWithoutParameterNotDefinedForType(propertyName, type); } else { throw Error.InstancePropertyWithSpecifiedParametersNotDefinedForType(propertyName, GetArgTypesString(arguments), type); } } return pi; } private static string GetArgTypesString(Expression[] arguments) { StringBuilder argTypesStr = new StringBuilder(); var isFirst = true; argTypesStr.Append("("); foreach (var t in arguments.Select(arg => arg.Type)) { if (!isFirst) { argTypesStr.Append(", "); } argTypesStr.Append(t.Name); isFirst = false; } argTypesStr.Append(")"); return argTypesStr.ToString(); } private static PropertyInfo FindProperty(Type type, string propertyName, Expression[] arguments, BindingFlags flags) { MemberInfo[] members = type.FindMembers(MemberTypes.Property, flags, Type.FilterNameIgnoreCase, propertyName); if (members == null || members.Length == 0) return null; PropertyInfo pi; var propertyInfos = members.Map(t => (PropertyInfo)t); int count = FindBestProperty(propertyInfos, arguments, out pi); if (count == 0) return null; if (count > 1) throw Error.PropertyWithMoreThanOneMatch(propertyName, type); return pi; } private static int FindBestProperty(IEnumerableproperties, Expression[] args, out PropertyInfo property) { int count = 0; property = null; foreach (PropertyInfo pi in properties) { if (pi != null && IsCompatible(pi, args)) { if (property == null) { property = pi; count = 1; } else { count++; } } } return count; } private static bool IsCompatible(PropertyInfo pi, Expression[] args) { MethodInfo mi; mi = pi.GetGetMethod(true); ParameterInfo[] parms; if (mi != null) { parms = mi.GetParametersCached(); } else { mi = pi.GetSetMethod(true); //The setter has an additional parameter for the value to set, //need to remove the last type to match the arguments. parms = mi.GetParametersCached().RemoveLast(); } if (mi == null) { return false; } if (args == null) { return parms.Length == 0; } if (parms.Length != args.Length) return false; for (int i = 0; i < args.Length; i++) { if (args[i] == null) return false; if (!TypeUtils.AreReferenceAssignable(parms[i].ParameterType, args[i].Type)) { return false; } } return true; } #endregion /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// Therepresenting the access to an indexed property. /// that represents the property to index. /// An array of objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, PropertyInfo indexer, params Expression[] arguments) { return Property(instance, indexer, (IEnumerable. )arguments); } /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// Therepresenting the access to an indexed property. /// that represents the property to index. /// An of objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, PropertyInfo indexer, IEnumerable. arguments) { var argList = arguments.ToReadOnly(); ValidateIndexedProperty(instance, indexer, ref argList); return new IndexExpression(instance, indexer, argList); } // CTS places no restrictions on properties (see ECMA-335 8.11.3), // so we validate that the property conforms to CLS rules here. // // Does reflection help us out at all? Expression.Property skips all of // these checks, so either it needs more checks or we need less here. private static void ValidateIndexedProperty(Expression instance, PropertyInfo property, ref ReadOnlyCollection argList) { // If both getter and setter specified, all their parameter types // should match, with exception of the last setter parameter which // should match the type returned by the get method. // Accessor parameters cannot be ByRef. ContractUtils.RequiresNotNull(property, "property"); if (property.PropertyType.IsByRef) throw Error.PropertyCannotHaveRefType(); if (property.PropertyType == typeof(void)) throw Error.PropertyTypeCannotBeVoid(); ParameterInfo[] getParameters = null; MethodInfo getter = property.GetGetMethod(true); if (getter != null) { getParameters = getter.GetParametersCached(); ValidateAccessor(instance, getter, getParameters, ref argList); } MethodInfo setter = property.GetSetMethod(true); if (setter != null) { ParameterInfo[] setParameters = setter.GetParametersCached(); if (setParameters.Length == 0) throw Error.SetterHasNoParams(); // valueType is the type of the value passed to the setter (last parameter) Type valueType = setParameters[setParameters.Length - 1].ParameterType; if (valueType.IsByRef) throw Error.PropertyCannotHaveRefType(); if (setter.ReturnType != typeof(void)) throw Error.SetterMustBeVoid(); if (property.PropertyType != valueType) throw Error.PropertyTyepMustMatchSetter(); if (getter != null) { if (getter.IsStatic ^ setter.IsStatic) throw Error.BothAccessorsMustBeStatic(); if (getParameters.Length != setParameters.Length - 1) throw Error.IndexesOfSetGetMustMatch(); for (int i = 0; i < getParameters.Length; i++) { if (getParameters[i].ParameterType != setParameters[i].ParameterType) throw Error.IndexesOfSetGetMustMatch(); } } else { ValidateAccessor(instance, setter, setParameters.RemoveLast(), ref argList); } } if (getter == null && setter == null) { throw Error.PropertyDoesNotHaveAccessor(property); } } private static void ValidateAccessor(Expression instance, MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); ValidateMethodInfo(method); if ((method.CallingConvention & CallingConventions.VarArgs) != 0) throw Error.AccessorsCannotHaveVarArgs(); if (method.IsStatic) { if (instance != null) throw Error.OnlyStaticMethodsHaveNullInstance(); } else { if (instance == null) throw Error.OnlyStaticMethodsHaveNullInstance(); RequiresCanRead(instance, "instance"); ValidateCallInstanceType(instance.Type, method); } ValidateAccessorArgumentTypes(method, indexes, ref arguments); } private static void ValidateAccessorArgumentTypes(MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection arguments) { if (indexes.Length > 0) { if (indexes.Length != arguments.Count) { throw Error.IncorrectNumberOfMethodCallArguments(method); } Expression[] newArgs = null; for (int i = 0, n = indexes.Length; i < n; i++) { Expression arg = arguments[i]; ParameterInfo pi = indexes[i]; RequiresCanRead(arg, "arguments"); Type pType = pi.ParameterType; if (pType.IsByRef) throw Error.AccessorsCannotHaveByRefArgs(); TypeUtils.ValidateType(pType); if (!TypeUtils.AreReferenceAssignable(pType, arg.Type)) { if (TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), pType) && pType.IsAssignableFrom(arg.GetType())) { arg = Expression.Quote(arg); } else { throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method); } } if (newArgs == null && arg != arguments[i]) { newArgs = new Expression[arguments.Count]; for (int j = 0; j < i; j++) { newArgs[j] = arguments[j]; } } if (newArgs != null) { newArgs[i] = arg; } } if (newArgs != null) { arguments = new TrueReadOnlyCollection (newArgs); } } else if (arguments.Count > 0) { throw Error.IncorrectNumberOfMethodCallArguments(method); } } #endregion } } // 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.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { /// /// Represents indexing a property or array. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.IndexExpressionProxy))] #endif public sealed class IndexExpression : Expression, IArgumentProvider { private readonly Expression _instance; private readonly PropertyInfo _indexer; private IList_arguments; internal IndexExpression( Expression instance, PropertyInfo indexer, IList arguments) { if (indexer == null) { Debug.Assert(instance != null && instance.Type.IsArray); Debug.Assert(instance.Type.GetArrayRank() == arguments.Count); } _instance = instance; _indexer = indexer; _arguments = arguments; } /// /// Returns the node type of this ///. (Inherited from .) /// The public sealed override ExpressionType NodeType { get { return ExpressionType.Index; } } ///that represents this expression. /// Gets the static type of the expression that this ///represents. (Inherited from .) /// The public sealed override Type Type { get { if (_indexer != null) { return _indexer.PropertyType; } return _instance.Type.GetElementType(); } } ///that represents the static type of the expression. /// An object to index. /// public Expression Object { get { return _instance; } } ////// Gets the public PropertyInfo Indexer { get { return _indexer; } } ///for the property if the expression represents an indexed property, returns null otherwise. /// /// Gets the arguments to be used to index the property or array. /// public ReadOnlyCollectionArguments { get { return ReturnReadOnly(ref _arguments); } } /// /// 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. /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public IndexExpression Update(Expression @object, IEnumerablearguments) { if (@object == Object && arguments == Arguments) { return this; } return Expression.MakeIndex(@object, Indexer, arguments); } Expression IArgumentProvider.GetArgument(int index) { return _arguments[index]; } int IArgumentProvider.ArgumentCount { get { return _arguments.Count; } } /// /// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitIndex(this); } internal Expression Rewrite(Expression instance, Expression[] arguments) { Debug.Assert(instance != null); Debug.Assert(arguments == null || arguments.Length == _arguments.Count); return Expression.MakeIndex(instance, _indexer, arguments ?? _arguments); } } public partial class Expression { ////// Creates an /// The object to which the property belongs. Should be null if the property is static(shared). /// Anthat represents accessing an indexed property in an object. /// representing the property to index. /// An IEnumerable{Expression} contaning the arguments to be used to index the property. /// The created public static IndexExpression MakeIndex(Expression instance, PropertyInfo indexer, IEnumerable. arguments) { if (indexer != null) { return Property(instance, indexer, arguments); } else { return ArrayAccess(instance, arguments); } } #region ArrayAccess /// /// Creates an /// An expression representing the array to index. /// An array containing expressions used to index the array. ///to access an array. /// The expression representing the array can be obtained by using the MakeMemberAccess method, /// or through NewArrayBounds or NewArrayInit. ///The created public static IndexExpression ArrayAccess(Expression array, params Expression[] indexes) { return ArrayAccess(array, (IEnumerable. )indexes); } /// /// Creates an /// An expression representing the array to index. /// Anto access an array. /// containing expressions used to index the array. /// The expression representing the array can be obtained by using the MakeMemberAccess method, /// or through NewArrayBounds or NewArrayInit. ///The created public static IndexExpression ArrayAccess(Expression array, IEnumerable. indexes) { RequiresCanRead(array, "array"); Type arrayType = array.Type; if (!arrayType.IsArray) { throw Error.ArgumentMustBeArray(); } var indexList = indexes.ToReadOnly(); if (arrayType.GetArrayRank() != indexList.Count) { throw Error.IncorrectNumberOfIndexes(); } foreach (Expression e in indexList) { RequiresCanRead(e, "indexes"); if (e.Type != typeof(int)) { throw Error.ArgumentMustBeArrayIndexType(); } } return new IndexExpression(array, null, indexList); } #endregion #region Property /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// The name of the indexer. /// An array ofrepresenting the access to an indexed property. /// objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, string propertyName, params Expression[] arguments) { RequiresCanRead(instance, "instance"); ContractUtils.RequiresNotNull(propertyName, "indexerName"); PropertyInfo pi = FindInstanceProperty(instance.Type, propertyName, arguments); return Property(instance, pi, arguments); } #region methods for finding a PropertyInfo by its name ///. /// The method finds the instance property with the specified name in a type. The property's type signature needs to be compatible with /// the arguments if it is a indexer. If the arguments is null or empty, we get a normal property. /// private static PropertyInfo FindInstanceProperty(Type type, string propertyName, Expression[] arguments) { // bind to public names first BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy; PropertyInfo pi = FindProperty(type, propertyName, arguments, flags); if (pi == null) { flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy; pi = FindProperty(type, propertyName, arguments, flags); } if (pi == null) { if (arguments == null || arguments.Length == 0) { throw Error.InstancePropertyWithoutParameterNotDefinedForType(propertyName, type); } else { throw Error.InstancePropertyWithSpecifiedParametersNotDefinedForType(propertyName, GetArgTypesString(arguments), type); } } return pi; } private static string GetArgTypesString(Expression[] arguments) { StringBuilder argTypesStr = new StringBuilder(); var isFirst = true; argTypesStr.Append("("); foreach (var t in arguments.Select(arg => arg.Type)) { if (!isFirst) { argTypesStr.Append(", "); } argTypesStr.Append(t.Name); isFirst = false; } argTypesStr.Append(")"); return argTypesStr.ToString(); } private static PropertyInfo FindProperty(Type type, string propertyName, Expression[] arguments, BindingFlags flags) { MemberInfo[] members = type.FindMembers(MemberTypes.Property, flags, Type.FilterNameIgnoreCase, propertyName); if (members == null || members.Length == 0) return null; PropertyInfo pi; var propertyInfos = members.Map(t => (PropertyInfo)t); int count = FindBestProperty(propertyInfos, arguments, out pi); if (count == 0) return null; if (count > 1) throw Error.PropertyWithMoreThanOneMatch(propertyName, type); return pi; } private static int FindBestProperty(IEnumerableproperties, Expression[] args, out PropertyInfo property) { int count = 0; property = null; foreach (PropertyInfo pi in properties) { if (pi != null && IsCompatible(pi, args)) { if (property == null) { property = pi; count = 1; } else { count++; } } } return count; } private static bool IsCompatible(PropertyInfo pi, Expression[] args) { MethodInfo mi; mi = pi.GetGetMethod(true); ParameterInfo[] parms; if (mi != null) { parms = mi.GetParametersCached(); } else { mi = pi.GetSetMethod(true); //The setter has an additional parameter for the value to set, //need to remove the last type to match the arguments. parms = mi.GetParametersCached().RemoveLast(); } if (mi == null) { return false; } if (args == null) { return parms.Length == 0; } if (parms.Length != args.Length) return false; for (int i = 0; i < args.Length; i++) { if (args[i] == null) return false; if (!TypeUtils.AreReferenceAssignable(parms[i].ParameterType, args[i].Type)) { return false; } } return true; } #endregion /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// Therepresenting the access to an indexed property. /// that represents the property to index. /// An array of objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, PropertyInfo indexer, params Expression[] arguments) { return Property(instance, indexer, (IEnumerable. )arguments); } /// /// Creates an /// The object to which the property belongs. If the property is static/shared, it must be null. /// Therepresenting the access to an indexed property. /// that represents the property to index. /// An of objects that are used to index the property. /// The created public static IndexExpression Property(Expression instance, PropertyInfo indexer, IEnumerable. arguments) { var argList = arguments.ToReadOnly(); ValidateIndexedProperty(instance, indexer, ref argList); return new IndexExpression(instance, indexer, argList); } // CTS places no restrictions on properties (see ECMA-335 8.11.3), // so we validate that the property conforms to CLS rules here. // // Does reflection help us out at all? Expression.Property skips all of // these checks, so either it needs more checks or we need less here. private static void ValidateIndexedProperty(Expression instance, PropertyInfo property, ref ReadOnlyCollection argList) { // If both getter and setter specified, all their parameter types // should match, with exception of the last setter parameter which // should match the type returned by the get method. // Accessor parameters cannot be ByRef. ContractUtils.RequiresNotNull(property, "property"); if (property.PropertyType.IsByRef) throw Error.PropertyCannotHaveRefType(); if (property.PropertyType == typeof(void)) throw Error.PropertyTypeCannotBeVoid(); ParameterInfo[] getParameters = null; MethodInfo getter = property.GetGetMethod(true); if (getter != null) { getParameters = getter.GetParametersCached(); ValidateAccessor(instance, getter, getParameters, ref argList); } MethodInfo setter = property.GetSetMethod(true); if (setter != null) { ParameterInfo[] setParameters = setter.GetParametersCached(); if (setParameters.Length == 0) throw Error.SetterHasNoParams(); // valueType is the type of the value passed to the setter (last parameter) Type valueType = setParameters[setParameters.Length - 1].ParameterType; if (valueType.IsByRef) throw Error.PropertyCannotHaveRefType(); if (setter.ReturnType != typeof(void)) throw Error.SetterMustBeVoid(); if (property.PropertyType != valueType) throw Error.PropertyTyepMustMatchSetter(); if (getter != null) { if (getter.IsStatic ^ setter.IsStatic) throw Error.BothAccessorsMustBeStatic(); if (getParameters.Length != setParameters.Length - 1) throw Error.IndexesOfSetGetMustMatch(); for (int i = 0; i < getParameters.Length; i++) { if (getParameters[i].ParameterType != setParameters[i].ParameterType) throw Error.IndexesOfSetGetMustMatch(); } } else { ValidateAccessor(instance, setter, setParameters.RemoveLast(), ref argList); } } if (getter == null && setter == null) { throw Error.PropertyDoesNotHaveAccessor(property); } } private static void ValidateAccessor(Expression instance, MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); ValidateMethodInfo(method); if ((method.CallingConvention & CallingConventions.VarArgs) != 0) throw Error.AccessorsCannotHaveVarArgs(); if (method.IsStatic) { if (instance != null) throw Error.OnlyStaticMethodsHaveNullInstance(); } else { if (instance == null) throw Error.OnlyStaticMethodsHaveNullInstance(); RequiresCanRead(instance, "instance"); ValidateCallInstanceType(instance.Type, method); } ValidateAccessorArgumentTypes(method, indexes, ref arguments); } private static void ValidateAccessorArgumentTypes(MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection arguments) { if (indexes.Length > 0) { if (indexes.Length != arguments.Count) { throw Error.IncorrectNumberOfMethodCallArguments(method); } Expression[] newArgs = null; for (int i = 0, n = indexes.Length; i < n; i++) { Expression arg = arguments[i]; ParameterInfo pi = indexes[i]; RequiresCanRead(arg, "arguments"); Type pType = pi.ParameterType; if (pType.IsByRef) throw Error.AccessorsCannotHaveByRefArgs(); TypeUtils.ValidateType(pType); if (!TypeUtils.AreReferenceAssignable(pType, arg.Type)) { if (TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), pType) && pType.IsAssignableFrom(arg.GetType())) { arg = Expression.Quote(arg); } else { throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method); } } if (newArgs == null && arg != arguments[i]) { newArgs = new Expression[arguments.Count]; for (int j = 0; j < i; j++) { newArgs[j] = arguments[j]; } } if (newArgs != null) { newArgs[i] = arg; } } if (newArgs != null) { arguments = new TrueReadOnlyCollection (newArgs); } } else if (arguments.Count > 0) { throw Error.IncorrectNumberOfMethodCallArguments(method); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AnalyzedTree.cs
- RolePrincipal.cs
- TextRangeProviderWrapper.cs
- DetailsView.cs
- VisualBasicSettingsConverter.cs
- CodeArgumentReferenceExpression.cs
- XdrBuilder.cs
- KeyInfo.cs
- XmlC14NWriter.cs
- DbModificationCommandTree.cs
- DataGridViewRowsRemovedEventArgs.cs
- RSAPKCS1SignatureFormatter.cs
- ArgumentOutOfRangeException.cs
- HttpModuleCollection.cs
- invalidudtexception.cs
- ReachPageContentCollectionSerializerAsync.cs
- ListView.cs
- Stacktrace.cs
- ManagementEventArgs.cs
- WsdlImporterElementCollection.cs
- MetadataArtifactLoaderCompositeResource.cs
- SystemResources.cs
- PermissionRequestEvidence.cs
- MessageAction.cs
- DSASignatureFormatter.cs
- ObjectConverter.cs
- AppearanceEditorPart.cs
- SegmentInfo.cs
- MenuItemBinding.cs
- TimeoutConverter.cs
- ImageClickEventArgs.cs
- HttpsHostedTransportConfiguration.cs
- SqlDataSource.cs
- MultiBinding.cs
- CompiledELinqQueryState.cs
- FontConverter.cs
- TemplateXamlParser.cs
- InvokeBinder.cs
- SiblingIterators.cs
- XmlSignatureProperties.cs
- IISMapPath.cs
- AlignmentYValidation.cs
- DataGridCell.cs
- KeyPressEvent.cs
- DataExchangeServiceBinder.cs
- OrderedDictionary.cs
- PersonalizationStateInfoCollection.cs
- QilLoop.cs
- ISAPIWorkerRequest.cs
- CodePrimitiveExpression.cs
- StateWorkerRequest.cs
- InternalDispatchObject.cs
- KeyGesture.cs
- MessageUtil.cs
- XamlFilter.cs
- ControlAdapter.cs
- sqlser.cs
- XmlSchemaElement.cs
- GeneralTransformGroup.cs
- IteratorAsyncResult.cs
- DbConnectionInternal.cs
- SkinBuilder.cs
- Point3DCollectionConverter.cs
- HiddenField.cs
- ListenerUnsafeNativeMethods.cs
- _FtpControlStream.cs
- DataBoundControlDesigner.cs
- ThicknessAnimationBase.cs
- HtmlPageAdapter.cs
- VirtualizingPanel.cs
- PeerPresenceInfo.cs
- BitmapEffect.cs
- PromptStyle.cs
- fixedPageContentExtractor.cs
- DoubleLinkListEnumerator.cs
- ContextMenuStrip.cs
- StringResourceManager.cs
- FunctionImportElement.cs
- BoundingRectTracker.cs
- SiteMapNodeItem.cs
- mediaeventshelper.cs
- ConditionCollection.cs
- BreakRecordTable.cs
- DbConnectionStringCommon.cs
- FileDialog_Vista.cs
- PropertyTabAttribute.cs
- IndexedEnumerable.cs
- ClientFormsAuthenticationCredentials.cs
- SecUtil.cs
- BindingMAnagerBase.cs
- ResourceDictionary.cs
- WebPartTracker.cs
- LiteralDesigner.cs
- SHA512Managed.cs
- GridViewUpdatedEventArgs.cs
- ApplicationCommands.cs
- RegisteredArrayDeclaration.cs
- ObjRef.cs
- RequestCachePolicy.cs
- ReadOnlyCollection.cs