throw new SystemException();
}
- private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
- {
- if (type.IsPointer || type.IsByRef || type == typeof(void))
- throw new ArgumentException(
- SR.Format(SR.Argument_NeverValidGenericArgument, type));
- }
-
- internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
- {
- if (genericArguments == null)
- throw new ArgumentNullException();
-
- for (int i = 0; i < genericArguments.Length; i++)
- {
- if (genericArguments[i] == null)
- throw new ArgumentNullException();
-
- ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
- }
-
- if (genericArguments.Length != genericParamters.Length)
- throw new ArgumentException(
- SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
- }
-
internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e)
{
RuntimeType[]? typeContext = null;
#region Invoke Member
- private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
- private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
- private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
- private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
- private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
- private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
private static readonly RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
[MethodImpl(MethodImplOptions.InternalCall)]
throw new ArgumentException(SR.Format(SR.Arg_ObjObjEx, value.GetType(), this));
}
- [DebuggerStepThrough]
- [DebuggerHidden]
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
- public override object? InvokeMember(
- string name, BindingFlags bindingFlags, Binder? binder, object? target,
- object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
- {
- if (IsGenericParameter)
- throw new InvalidOperationException(SR.Arg_GenericParameter);
-
- if ((bindingFlags & InvocationMask) == 0)
- // "Must specify binding flags describing the invoke operation required."
- throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
-
- // Provide a default binding mask if none is provided
- if ((bindingFlags & MemberBindingMask) == 0)
- {
- bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
-
- if ((bindingFlags & BindingFlags.CreateInstance) == 0)
- bindingFlags |= BindingFlags.Static;
- }
-
- // There must not be more named parameters than provided arguments
- if (namedParams != null)
- {
- if (providedArgs != null)
- {
- if (namedParams.Length > providedArgs.Length)
- throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
- }
- else
- {
- if (namedParams.Length != 0)
- throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
- }
- }
-
-#if FEATURE_COMINTEROP
- if (target != null && target.GetType().IsCOMObject)
- {
- const BindingFlags ClassicBindingMask =
- BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
- BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
-
- if ((bindingFlags & ClassicBindingMask) == 0)
- throw new ArgumentException(SR.Arg_COMAccess, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
- throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
- throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
- throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- bool[]? isByRef = modifiers?[0].IsByRefArray;
-
- // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
- int lcid = (culture == null ? 0x0409 : culture.LCID);
-
- // If a request to not wrap exceptions was made, we will unwrap
- // the TargetInvocationException since that is what will be thrown.
- bool unwrapExceptions = (bindingFlags & BindingFlags.DoNotWrapExceptions) != 0;
- try
- {
- return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
- }
- catch (TargetInvocationException e) when (unwrapExceptions)
- {
- // For target invocation exceptions, we need to unwrap the inner exception and
- // re-throw it.
- throw e.InnerException!;
- }
- }
-#endif // FEATURE_COMINTEROP
-
- if (namedParams != null && Array.IndexOf(namedParams, null!) != -1)
- throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
-
- int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
-
- binder ??= DefaultBinder;
-
- // Delegate to Activator.CreateInstance
- if ((bindingFlags & BindingFlags.CreateInstance) != 0)
- {
- if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
- // "Can not specify both CreateInstance and another access type."
- throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
-
- return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
- }
-
- // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
- if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
- bindingFlags |= BindingFlags.SetProperty;
-
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (name.Length == 0 || name.Equals("[DISPID=0]"))
- {
- // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
- name = GetDefaultMemberName()! ?? "ToString";
- }
-
- // GetField or SetField
- bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
- bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
-
- if (IsGetField || IsSetField)
- {
- if (IsGetField)
- {
- if (IsSetField)
- throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.SetProperty) != 0)
- throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
- }
- else
- {
- Debug.Assert(IsSetField);
-
- if (providedArgs == null)
- throw new ArgumentNullException(nameof(providedArgs));
-
- if ((bindingFlags & BindingFlags.GetProperty) != 0)
- throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
- }
-
- // Lookup Field
- FieldInfo? selFld = null;
- FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
-
- Debug.Assert(flds != null);
-
- if (flds.Length == 1)
- {
- selFld = flds[0];
- }
- else if (flds.Length > 0)
- {
- selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
- }
-
- if (selFld != null)
- {
- // Invocation on a field
- if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(Array)))
- {
- // Invocation of an array Field
- int idxCnt;
- if ((bindingFlags & BindingFlags.GetField) != 0)
- {
- idxCnt = argCnt;
- }
- else
- {
- idxCnt = argCnt - 1;
- }
-
- if (idxCnt > 0)
- {
- // Verify that all of the index values are ints
- int[] idx = new int[idxCnt];
- for (int i = 0; i < idxCnt; i++)
- {
- try
- {
- idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
- }
- catch (InvalidCastException)
- {
- throw new ArgumentException(SR.Arg_IndexMustBeInt);
- }
- }
-
- // Set or get the value...
- Array a = (Array)selFld.GetValue(target)!;
-
- // Set or get the value in the array
- if ((bindingFlags & BindingFlags.GetField) != 0)
- {
- return a.GetValue(idx);
- }
- else
- {
- a.SetValue(providedArgs![idxCnt], idx);
- return null;
- }
- }
- }
-
- if (IsGetField)
- {
- if (argCnt != 0)
- throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
-
- return selFld.GetValue(target);
- }
- else
- {
- if (argCnt != 1)
- throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
-
- selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
- return null;
- }
- }
-
- if ((bindingFlags & BinderNonFieldGetSet) == 0)
- throw new MissingFieldException(FullName, name);
- }
-
- // @Legacy - This is RTM behavior
- bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
- bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
-
- if (isGetProperty || isSetProperty)
- {
- if (isGetProperty)
- {
- Debug.Assert(!IsSetField);
-
- if (isSetProperty)
- throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
- }
- else
- {
- Debug.Assert(isSetProperty);
-
- Debug.Assert(!IsGetField);
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
- }
- }
-
- MethodInfo[]? finalists = null;
- MethodInfo? finalist = null;
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- {
- // Lookup Methods
- MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
- List<MethodInfo>? results = null;
-
- for (int i = 0; i < semiFinalists.Length; i++)
- {
- MethodInfo semiFinalist = semiFinalists[i];
- Debug.Assert(semiFinalist != null);
-
- if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
- continue;
-
- if (finalist == null)
- {
- finalist = semiFinalist;
- }
- else
- {
- results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
- results.Add(semiFinalist);
- }
- }
-
- if (results != null)
- {
- Debug.Assert(results.Count > 1);
- finalists = results.ToArray();
- }
- }
-
- Debug.Assert(finalists == null || finalist != null);
-
- // BindingFlags.GetProperty or BindingFlags.SetProperty
- if (finalist == null && isGetProperty || isSetProperty)
- {
- // Lookup Property
- PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
- List<MethodInfo>? results = null;
-
- for (int i = 0; i < semiFinalists.Length; i++)
- {
- MethodInfo? semiFinalist = null;
-
- if (isSetProperty)
- {
- semiFinalist = semiFinalists[i].GetSetMethod(true);
- }
- else
- {
- semiFinalist = semiFinalists[i].GetGetMethod(true);
- }
-
- if (semiFinalist == null)
- continue;
-
- if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
- continue;
-
- if (finalist == null)
- {
- finalist = semiFinalist;
- }
- else
- {
- results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
- results.Add(semiFinalist);
- }
- }
-
- if (results != null)
- {
- Debug.Assert(results.Count > 1);
- finalists = results.ToArray();
- }
- }
-
- if (finalist != null)
- {
- // Invoke
- if (finalists == null &&
- argCnt == 0 &&
- finalist.GetParametersNoCopy().Length == 0 &&
- (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
- {
- return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
- }
-
- finalists ??= new MethodInfo[] { finalist };
- providedArgs ??= Array.Empty<object>();
- object? state = null;
- MethodBase? invokeMethod = null;
-
- try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs!, modifiers, culture, namedParams, out state); }
- catch (MissingMethodException) { }
-
- if (invokeMethod == null)
- throw new MissingMethodException(FullName, name);
-
- object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
-
- if (state != null)
- binder.ReorderArgumentArray(ref providedArgs, state);
-
- return result;
- }
-
- throw new MissingMethodException(FullName, name);
- }
-
#endregion
#endregion
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
return false;
}
+ [DebuggerStepThrough]
+ [DebuggerHidden]
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+ public override object? InvokeMember(
+ string name, BindingFlags bindingFlags, Binder? binder, object? target,
+ object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
+ {
+ const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
+ const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
+ const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
+ const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
+ const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
+ const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
+
+ if (IsGenericParameter)
+ throw new InvalidOperationException(SR.Arg_GenericParameter);
+
+ if ((bindingFlags & InvocationMask) == 0)
+ // "Must specify binding flags describing the invoke operation required."
+ throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
+
+ // Provide a default binding mask if none is provided
+ if ((bindingFlags & MemberBindingMask) == 0)
+ {
+ bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
+
+ if ((bindingFlags & BindingFlags.CreateInstance) == 0)
+ bindingFlags |= BindingFlags.Static;
+ }
+
+ // There must not be more named parameters than provided arguments
+ if (namedParams != null)
+ {
+ if (providedArgs != null)
+ {
+ if (namedParams.Length > providedArgs.Length)
+ throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
+ }
+ else
+ {
+ if (namedParams.Length != 0)
+ throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
+ }
+ }
+
+#if FEATURE_COMINTEROP
+ if (target != null && target.GetType().IsCOMObject)
+ {
+ const BindingFlags ClassicBindingMask =
+ BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
+ BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
+
+ if ((bindingFlags & ClassicBindingMask) == 0)
+ throw new ArgumentException(SR.Arg_COMAccess, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
+ throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
+ throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ bool[]? isByRef = modifiers?[0].IsByRefArray;
+
+ // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
+ int lcid = (culture == null ? 0x0409 : culture.LCID);
+
+ // If a request to not wrap exceptions was made, we will unwrap
+ // the TargetInvocationException since that is what will be thrown.
+ bool unwrapExceptions = (bindingFlags & BindingFlags.DoNotWrapExceptions) != 0;
+ try
+ {
+ return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
+ }
+ catch (TargetInvocationException e) when (unwrapExceptions)
+ {
+ // For target invocation exceptions, we need to unwrap the inner exception and
+ // re-throw it.
+ throw e.InnerException!;
+ }
+ }
+#endif // FEATURE_COMINTEROP
+
+ if (namedParams != null && Array.IndexOf(namedParams, null!) != -1)
+ throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
+
+ int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
+
+ binder ??= DefaultBinder;
+
+ // Delegate to Activator.CreateInstance
+ if ((bindingFlags & BindingFlags.CreateInstance) != 0)
+ {
+ if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
+ // "Can not specify both CreateInstance and another access type."
+ throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
+
+ return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
+ }
+
+ // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
+ if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
+ bindingFlags |= BindingFlags.SetProperty;
+
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (name.Length == 0 || name.Equals("[DISPID=0]"))
+ {
+ // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
+ name = GetDefaultMemberName()! ?? "ToString";
+ }
+
+ // GetField or SetField
+ bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
+ bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
+
+ if (IsGetField || IsSetField)
+ {
+ if (IsGetField)
+ {
+ if (IsSetField)
+ throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.SetProperty) != 0)
+ throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
+ }
+ else
+ {
+ Debug.Assert(IsSetField);
+
+ if (providedArgs == null)
+ throw new ArgumentNullException(nameof(providedArgs));
+
+ if ((bindingFlags & BindingFlags.GetProperty) != 0)
+ throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
+
+ if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+ throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
+ }
+
+ // Lookup Field
+ FieldInfo? selFld = null;
+ FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
+
+ Debug.Assert(flds != null);
+
+ if (flds.Length == 1)
+ {
+ selFld = flds[0];
+ }
+ else if (flds.Length > 0)
+ {
+ selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
+ }
+
+ if (selFld != null)
+ {
+ // Invocation on a field
+ if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(Array)))
+ {
+ // Invocation of an array Field
+ int idxCnt;
+ if ((bindingFlags & BindingFlags.GetField) != 0)
+ {
+ idxCnt = argCnt;
+ }
+ else
+ {
+ idxCnt = argCnt - 1;
+ }
+
+ if (idxCnt > 0)
+ {
+ // Verify that all of the index values are ints
+ int[] idx = new int[idxCnt];
+ for (int i = 0; i < idxCnt; i++)
+ {
+ try
+ {
+ idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
+ }
+ catch (InvalidCastException)
+ {
+ throw new ArgumentException(SR.Arg_IndexMustBeInt);
+ }
+ }
+
+ // Set or get the value...
+ Array a = (Array)selFld.GetValue(target)!;
+
+ // Set or get the value in the array
+ if ((bindingFlags & BindingFlags.GetField) != 0)
+ {
+ return a.GetValue(idx);
+ }
+ else
+ {
+ a.SetValue(providedArgs![idxCnt], idx);
+ return null;
+ }
+ }
+ }
+
+ if (IsGetField)
+ {
+ if (argCnt != 0)
+ throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
+
+ return selFld.GetValue(target);
+ }
+ else
+ {
+ if (argCnt != 1)
+ throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
+
+ selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
+ return null;
+ }
+ }
+
+ if ((bindingFlags & BinderNonFieldGetSet) == 0)
+ throw new MissingFieldException(FullName, name);
+ }
+
+ // @Legacy - This is RTM behavior
+ bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
+ bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
+
+ if (isGetProperty || isSetProperty)
+ {
+ if (isGetProperty)
+ {
+ Debug.Assert(!IsSetField);
+
+ if (isSetProperty)
+ throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
+ }
+ else
+ {
+ Debug.Assert(isSetProperty);
+
+ Debug.Assert(!IsGetField);
+
+ if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+ throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
+ }
+ }
+
+ MethodInfo[]? finalists = null;
+ MethodInfo? finalist = null;
+
+ if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+ {
+ // Lookup Methods
+ MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
+ List<MethodInfo>? results = null;
+
+ for (int i = 0; i < semiFinalists.Length; i++)
+ {
+ MethodInfo semiFinalist = semiFinalists[i];
+ Debug.Assert(semiFinalist != null);
+
+ if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+ continue;
+
+ if (finalist == null)
+ {
+ finalist = semiFinalist;
+ }
+ else
+ {
+ results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
+ results.Add(semiFinalist);
+ }
+ }
+
+ if (results != null)
+ {
+ Debug.Assert(results.Count > 1);
+ finalists = results.ToArray();
+ }
+ }
+
+ Debug.Assert(finalists == null || finalist != null);
+
+ // BindingFlags.GetProperty or BindingFlags.SetProperty
+ if (finalist == null && isGetProperty || isSetProperty)
+ {
+ // Lookup Property
+ PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
+ List<MethodInfo>? results = null;
+
+ for (int i = 0; i < semiFinalists.Length; i++)
+ {
+ MethodInfo? semiFinalist = null;
+
+ if (isSetProperty)
+ {
+ semiFinalist = semiFinalists[i].GetSetMethod(true);
+ }
+ else
+ {
+ semiFinalist = semiFinalists[i].GetGetMethod(true);
+ }
+
+ if (semiFinalist == null)
+ continue;
+
+ if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+ continue;
+
+ if (finalist == null)
+ {
+ finalist = semiFinalist;
+ }
+ else
+ {
+ results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
+ results.Add(semiFinalist);
+ }
+ }
+
+ if (results != null)
+ {
+ Debug.Assert(results.Count > 1);
+ finalists = results.ToArray();
+ }
+ }
+
+ if (finalist != null)
+ {
+ // Invoke
+ if (finalists == null &&
+ argCnt == 0 &&
+ finalist.GetParametersNoCopy().Length == 0 &&
+ (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
+ {
+ return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
+ }
+
+ finalists ??= new MethodInfo[] { finalist };
+ providedArgs ??= Array.Empty<object>();
+ object? state = null;
+ MethodBase? invokeMethod = null;
+
+ try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs!, modifiers, culture, namedParams, out state); }
+ catch (MissingMethodException) { }
+
+ if (invokeMethod == null)
+ throw new MissingMethodException(FullName, name);
+
+ object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
+
+ if (state != null)
+ binder.ReorderArgumentArray(ref providedArgs, state);
+
+ return result;
+ }
+
+ throw new MissingMethodException(FullName, name);
+ }
+
private RuntimeType? GetBaseType()
{
if (IsInterface)
return RuntimeTypeHandle.GetBaseType(this);
}
+
+ private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
+ {
+ if (type.IsPointer || type.IsByRef || type == typeof(void))
+ throw new ArgumentException(
+ SR.Format(SR.Argument_NeverValidGenericArgument, type));
+ }
+
+ internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
+ {
+ if (genericArguments == null)
+ throw new ArgumentNullException();
+
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ if (genericArguments[i] == null)
+ throw new ArgumentNullException();
+
+ ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
+ }
+
+ if (genericArguments.Length != genericParamters.Length)
+ throw new ArgumentException(
+ SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
+ }
}
}
typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
}
- private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
- {
- if (type.IsPointer || type.IsByRef || type == typeof(void))
- throw new ArgumentException(
- SR.Format(SR.Argument_NeverValidGenericArgument, type));
- }
-
- internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
- {
- if (genericArguments == null)
- throw new ArgumentNullException();
-
- for (int i = 0; i < genericArguments.Length; i++)
- {
- if (genericArguments[i] == null)
- throw new ArgumentNullException();
-
- ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
- }
-
- if (genericArguments.Length != genericParamters.Length)
- throw new ArgumentException(
- SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
- }
-
private static void SplitName(string? fullname, out string? name, out string? ns)
{
name = null;
#endregion
- #region Invoke Member
- private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
- private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
- private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
- private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
- private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
- private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
- public override object? InvokeMember(
- string name, BindingFlags bindingFlags, Binder? binder, object? target,
- object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
- {
- if (IsGenericParameter)
- throw new InvalidOperationException(SR.Arg_GenericParameter);
-
- #region Preconditions
- if ((bindingFlags & InvocationMask) == 0)
- // "Must specify binding flags describing the invoke operation required."
- throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
-
- // Provide a default binding mask if none is provided
- if ((bindingFlags & MemberBindingMask) == 0)
- {
- bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
-
- if ((bindingFlags & BindingFlags.CreateInstance) == 0)
- bindingFlags |= BindingFlags.Static;
- }
-
- // There must not be more named parameters than provided arguments
- if (namedParams != null)
- {
- if (providedArgs != null)
- {
- if (namedParams.Length > providedArgs.Length)
- // "Named parameter array can not be bigger than argument array."
- throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
- }
- else
- {
- if (namedParams.Length != 0)
- // "Named parameter array can not be bigger than argument array."
- throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
- }
- }
- #endregion
-
- #region Check that any named paramters are not null
- if (namedParams != null && Array.IndexOf<string?>(namedParams, null) != -1)
- // "Named parameter value must not be null."
- throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
- #endregion
-
- int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
-
- #region Get a Binder
- if (binder == null)
- binder = DefaultBinder;
-
- #endregion
-
- #region Delegate to Activator.CreateInstance
- if ((bindingFlags & BindingFlags.CreateInstance) != 0)
- {
- if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
- // "Can not specify both CreateInstance and another access type."
- throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
-
- return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
- }
- #endregion
-
- // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
- if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
- bindingFlags |= BindingFlags.SetProperty;
-
- #region Name
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
- {
- name = GetDefaultMemberName() ?? "ToString"; // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
- }
- #endregion
-
- #region GetField or SetField
- bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
- bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
-
- if (IsGetField || IsSetField)
- {
- #region Preconditions
- if (IsGetField)
- {
- if (IsSetField)
- // "Can not specify both Get and Set on a field."
- throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.SetProperty) != 0)
- // "Can not specify both GetField and SetProperty."
- throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
- }
- else
- {
- Debug.Assert(IsSetField);
-
- if (providedArgs == null)
- throw new ArgumentNullException(nameof(providedArgs));
-
- if ((bindingFlags & BindingFlags.GetProperty) != 0)
- // "Can not specify both SetField and GetProperty."
- throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- // "Can not specify Set on a Field and Invoke on a method."
- throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
- }
- #endregion
-
- #region Lookup Field
- FieldInfo? selFld = null;
- FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
-
- Debug.Assert(flds != null);
-
- if (flds.Length == 1)
- {
- selFld = flds[0];
- }
- else if (flds.Length > 0)
- {
- selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
- }
- #endregion
-
- if (selFld != null)
- {
- #region Invocation on a field
- if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(System.Array)))
- {
- #region Invocation of an array Field
- int idxCnt;
-
- if ((bindingFlags & BindingFlags.GetField) != 0)
- {
- idxCnt = argCnt;
- }
- else
- {
- idxCnt = argCnt - 1;
- }
-
- if (idxCnt > 0)
- {
- // Verify that all of the index values are ints
- int[] idx = new int[idxCnt];
- for (int i = 0; i < idxCnt; i++)
- {
- try
- {
- idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
- }
- catch (InvalidCastException)
- {
- throw new ArgumentException(SR.Arg_IndexMustBeInt);
- }
- }
-
- // Set or get the value...
- Array a = (Array)selFld.GetValue(target)!;
-
- // Set or get the value in the array
- if ((bindingFlags & BindingFlags.GetField) != 0)
- {
- return a.GetValue(idx);
- }
- else
- {
- a.SetValue(providedArgs![idxCnt], idx);
- return null;
- }
- }
- #endregion
- }
-
- if (IsGetField)
- {
- #region Get the field value
- if (argCnt != 0)
- throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
-
- return selFld.GetValue(target);
- #endregion
- }
- else
- {
- #region Set the field Value
- if (argCnt != 1)
- throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
-
- selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
-
- return null;
- #endregion
- }
- #endregion
- }
-
- if ((bindingFlags & BinderNonFieldGetSet) == 0)
- throw new MissingFieldException(FullName, name);
- }
- #endregion
-
- #region Caching Logic
- /*
- bool useCache = false;
-
- // Note that when we add something to the cache, we are careful to ensure
- // that the actual providedArgs matches the parameters of the method. Otherwise,
- // some default argument processing has occurred. We don't want anyone
- // else with the same (insufficient) number of actual arguments to get a
- // cache hit because then they would bypass the default argument processing
- // and the invocation would fail.
- if (bDefaultBinder && namedParams == null && argCnt < 6)
- useCache = true;
-
- if (useCache)
- {
- MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
-
- if (invokeMethod != null)
- return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
- }
- */
- #endregion
-
- #region Property PreConditions
- // @Legacy - This is RTM behavior
- bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
- bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
-
- if (isGetProperty || isSetProperty)
- {
- #region Preconditions
- if (isGetProperty)
- {
- Debug.Assert(!IsSetField);
-
- if (isSetProperty)
- throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
- }
- else
- {
- Debug.Assert(isSetProperty);
-
- Debug.Assert(!IsGetField);
-
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
- }
- #endregion
- }
- #endregion
-
- MethodInfo[]? finalists = null;
- MethodInfo? finalist = null;
-
- #region BindingFlags.InvokeMethod
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- {
- #region Lookup Methods
- MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
- List<MethodInfo>? results = null;
-
- for (int i = 0; i < semiFinalists.Length; i++)
- {
- MethodInfo semiFinalist = semiFinalists[i];
- Debug.Assert(semiFinalist != null);
-
- if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
- continue;
-
- if (finalist == null)
- {
- finalist = semiFinalist;
- }
- else
- {
- results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
- results.Add(semiFinalist);
- }
- }
-
- if (results != null)
- {
- Debug.Assert(results.Count > 1);
- finalists = new MethodInfo[results.Count];
- results.CopyTo(finalists);
- }
- #endregion
- }
- #endregion
-
- Debug.Assert(finalists == null || finalist != null);
-
- #region BindingFlags.GetProperty or BindingFlags.SetProperty
- if (finalist == null && isGetProperty || isSetProperty)
- {
- #region Lookup Property
- PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
- List<MethodInfo>? results = null;
-
- for (int i = 0; i < semiFinalists.Length; i++)
- {
- MethodInfo? semiFinalist = null;
-
- if (isSetProperty)
- {
- semiFinalist = semiFinalists[i].GetSetMethod(true);
- }
- else
- {
- semiFinalist = semiFinalists[i].GetGetMethod(true);
- }
-
- if (semiFinalist == null)
- continue;
-
- if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
- continue;
-
- if (finalist == null)
- {
- finalist = semiFinalist;
- }
- else
- {
- results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
- results.Add(semiFinalist);
- }
- }
-
- if (results != null)
- {
- Debug.Assert(results.Count > 1);
- finalists = new MethodInfo[results.Count];
- results.CopyTo(finalists);
- }
- #endregion
- }
- #endregion
-
- if (finalist != null)
- {
- #region Invoke
- if (finalists == null &&
- argCnt == 0 &&
- finalist.GetParametersNoCopy().Length == 0 &&
- (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
- {
- //if (useCache && argCnt == props[0].GetParameters().Length)
- // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
-
- return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
- }
-
- finalists ??= new MethodInfo[] { finalist };
- providedArgs ??= Array.Empty<object>();
-
- object? state = null;
-
-
- MethodBase? invokeMethod = null;
-
- try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
- catch (MissingMethodException) { }
-
- if (invokeMethod == null)
- throw new MissingMethodException(FullName, name);
-
- //if (useCache && argCnt == invokeMethod.GetParameters().Length)
- // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
-
- object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
-
- if (state != null)
- binder.ReorderArgumentArray(ref providedArgs, state);
-
- return result;
- #endregion
- }
-
- throw new MissingMethodException(FullName, name);
- }
- #endregion
-
public static bool operator ==(RuntimeType? left, RuntimeType? right)
{
return ReferenceEquals(left, right);