// 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 <Expression> 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; var getter = property.GetGetMethod(true); if (getter != null) { getParameters = getter.GetParameters(); ValidateAccessor(instance, getter, getParameters, ref argList); } var setter = property.GetSetMethod(true); if (setter != null) { var setParameters = setter.GetParameters(); if (setParameters.Length == 0) { throw Error.SetterHasNoParams(); } // valueType is the type of the value passed to the setter (last parameter) var 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 (var 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); } }
// 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 indexer, string paramName, ref ReadOnlyCollection <Expression> 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(indexer, paramName); if (indexer.PropertyType.IsByRef) { throw Error.PropertyCannotHaveRefType(paramName); } if (indexer.PropertyType == typeof(void)) { throw Error.PropertyTypeCannotBeVoid(paramName); } ParameterInfo[]? getParameters = null; MethodInfo?getter = indexer.GetGetMethod(nonPublic: true); if (getter != null) { if (getter.ReturnType != indexer.PropertyType) { throw Error.PropertyTypeMustMatchGetter(paramName); } getParameters = getter.GetParametersCached(); ValidateAccessor(instance, getter, getParameters, ref argList, paramName); } MethodInfo?setter = indexer.GetSetMethod(nonPublic: true); if (setter != null) { ParameterInfo[] setParameters = setter.GetParametersCached(); if (setParameters.Length == 0) { throw Error.SetterHasNoParams(paramName); } // 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(paramName); } if (setter.ReturnType != typeof(void)) { throw Error.SetterMustBeVoid(paramName); } if (indexer.PropertyType != valueType) { throw Error.PropertyTypeMustMatchSetter(paramName); } if (getter != null) { if (getter.IsStatic ^ setter.IsStatic) { throw Error.BothAccessorsMustBeStatic(paramName); } if (getParameters !.Length != setParameters.Length - 1) { throw Error.IndexesOfSetGetMustMatch(paramName); } for (int i = 0; i < getParameters.Length; i++) { if (getParameters[i].ParameterType != setParameters[i].ParameterType) { throw Error.IndexesOfSetGetMustMatch(paramName); } } } else { ValidateAccessor(instance, setter, setParameters.RemoveLast(), ref argList, paramName); } } else if (getter == null) { throw Error.PropertyDoesNotHaveAccessor(indexer, paramName); } }