/// <summary> /// Performs the call to the method defined by a previous <see cref="IMethodCall.Method"/> /// call, with the parameters specified by the <see cref="IMethodOperations.AddParameter"/> calls /// casting the return value to the specified type. /// </summary> /// <typeparam name="T">Type of the data returned by the method call</typeparam> /// <returns> /// The data returned by the method call, casted to the <typeparamref name="T">T type param</typeparamref> /// </returns> /// <remarks> /// The type parameter T must match the type of data returned by the method call /// access or an exception will be throw. /// </remarks> /// <exception cref="InvalidCastException"> /// If the type parameter T does not match the type of data returned, thus a casting /// could not be performed /// </exception> public T Invoke <T>() { object retValue; object[] args; args = InnerParameterBuilder.GetParametersAsArray(); if (InnerParameterBuilder.Count <= 0) { try { CommonLateBindingOperations.CallOperation( InstanceObject, OperationName, args, out retValue, EOperationType.Method); } catch { throw; } finally { ClearCall(); } } else { ParameterModifier refParams = new ParameterModifier(args.Length); for (int i = 0; i < args.Length; ++i) { refParams[i] = InnerParameterBuilder.GetReferenceParameterList()[i]; } try { CommonLateBindingOperations.CallOperation( InstanceObject, OperationName, args, out retValue, refParams, EOperationType.Method); } catch { throw; } finally { ClearCall(); } } LastCallParameters = args; return(CommonLateBindingOperations.ComputeReturnType <T>(retValue)); }
/// <summary> /// Performs a Set operation to modify data /// </summary> /// <param name="obj">New value </param> /// <remarks> /// The type of data passed as parameter /// must match the type of data we are trying to modify or an /// exception will be throw. /// </remarks> public void Set(object obj) { if (obj == null) { throw new ArgumentNullException(); } if (OperationName == string.Empty) { throw new NoOperationNameDefinedException(); } object retVal; object[] args; EOperationType op; if (OperationType == EGetSetInvokerOperation.Index) { op = EOperationType.PropertySet; List <object> tmp = new List <object>(InnerParameterBuilder.GetParametersAsArray()); tmp.Add(obj); args = tmp.ToArray(); } else { op = OperationType == EGetSetInvokerOperation.Property ? EOperationType.PropertySet : EOperationType.FieldSet; args = new object[] { obj }; } try { CommonLateBindingOperations.CallOperation( InstanceObject, OperationName, args, out retVal, op); } catch { throw; } finally { ClearCall(); } }
/// <summary> /// Performs indexer access over a type. /// </summary> /// <param name="indexList">object used as indexer</param> /// <returns> /// An <see cref="IGetSetOperations"/> that will establish the operation to /// perform over the specifyed index. /// </returns> public IGetSetOperations Index(params object[] indexList) { if (OperationName != string.Empty) { throw new AlreadyDefinedOperationNameException(); } OperationName = "Item"; OperationType = EGetSetInvokerOperation.Index; foreach (object idx in indexList) { InnerParameterBuilder.AddParameter(idx); } return(this); }
/// <summary> /// Adds a parameter to the method call, passed with reference semantics /// </summary> /// <param name="value">object to be passed as parameter</param> /// <returns> /// A reference to the instance which called this operation. /// </returns> public IMethodOperations AddRefParameter(object value) { InnerParameterBuilder.AddRefParameter(value); return(this); }
public IGetSetOperations PropertyParam(object value) { InnerParameterBuilder.AddParameter(value); return(this); }
/// <summary> /// Performs a Get operation to retrieve data, and returns it casted to the specified type. /// </summary> /// <typeparam name="T">Type of the data accessed</typeparam> /// <returns> /// The data accessed, casted to the <typeparamref name="T">T type param</typeparamref> /// </returns> /// <remarks> /// The type parameter T must match the type of data we are trying to /// access or an exception will be throw. /// </remarks> /// <exception cref="InvalidCastException"> /// If the type parameter T does not match the type of data accessed, thus a casting /// could not be performed /// </exception> public T Get <T>() { if (OperationName == string.Empty) { throw new NoOperationNameDefinedException(); } object retVal = null; object[] args = null; EOperationType op; if (OperationType == EGetSetInvokerOperation.Index || InnerParameterBuilder.Count > 0) { op = EOperationType.PropertyGet; args = InnerParameterBuilder.GetParametersAsArray(); } else { op = (OperationType == EGetSetInvokerOperation.Property) ? EOperationType.PropertyGet : EOperationType.FieldGet; } try { CommonLateBindingOperations.CallOperation( InstanceObject, OperationName, args, out retVal, op); } catch { // Sometimes -like when using Office Interop- the index get operation // must be treated as a method if (OperationType == EGetSetInvokerOperation.Index) { op = EOperationType.Method; try { CommonLateBindingOperations.CallOperation( InstanceObject, OperationName, args, out retVal, op); } catch { throw; } } else { throw; } } finally { ClearCall(); } return(CommonLateBindingOperations.ComputeReturnType <T>(retVal)); }
/// <summary> /// Once a late binding call is performed after calling Invoke, Get or Set methods, /// reinitialices the structures to allow making a distint call /// </summary> private void ClearCall() { OperationType = null; OperationName = string.Empty; InnerParameterBuilder.Clear(); }