示例#1
0
 /// <summary>
 /// Create a <see cref="Call"/>.
 /// </summary>
 public Call(MethodDecl methodDecl, params Expression[] arguments)
     : this(methodDecl.CreateRef(), arguments)
 {
 }
        /// <summary>
        /// Create (or re-create) the compiler-generated invoke methods and constructor.
        /// This method should be called whenever the parameters of the delegate are set or changed.
        /// </summary>
        public void GenerateMethods()
        {
            // Remove any existing methods before generating them - since the Body is compiler-generated just
            // to hold these methods, we can just re-create it.
            Body = new Block {
                IsGenerated = true
            };

            // The Invoke method has the same parameters as the delegate, and the same return type
            MethodDecl invokeDecl = new MethodDecl("Invoke", (Expression)_returnType.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };

            invokeDecl.Parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, invokeDecl) : null);
            Add(invokeDecl);

            // The BeginInvoke method has the same parameters as the delegate, plus 2 extra ones, and a return type of IAsyncResult
            MethodDecl beginInvokeDecl = new MethodDecl("BeginInvoke", (TypeRef)TypeRef.IAsyncResultRef.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };
            ChildList <ParameterDecl> parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, beginInvokeDecl) : new ChildList <ParameterDecl>(beginInvokeDecl));

            parameters.Add(new ParameterDecl("callback", (TypeRef)TypeRef.AsyncCallbackRef.Clone()));
            parameters.Add(new ParameterDecl("object", (TypeRef)TypeRef.ObjectRef.Clone()));
            beginInvokeDecl.Parameters = parameters;
            Add(beginInvokeDecl);

            // The EndInvoke method has any 'ref' or 'out' parameters of the delegate, plus 1 extra one, and the same return type
            MethodDecl endInvokeDecl = new MethodDecl("EndInvoke", (Expression)_returnType.Clone(), Modifiers.Public)
            {
                IsGenerated = true
            };

            parameters = new ChildList <ParameterDecl>(endInvokeDecl);
            if (_parameters != null)
            {
                foreach (ParameterDecl parameterDecl in _parameters)
                {
                    if (parameterDecl.IsRef || parameterDecl.IsOut)
                    {
                        parameters.Add((ParameterDecl)parameterDecl.Clone());
                    }
                }
            }
            parameters.Add(new ParameterDecl("result", (TypeRef)TypeRef.IAsyncResultRef.Clone()));
            endInvokeDecl.Parameters = parameters;
            Add(endInvokeDecl);

            // Delegates have a constructor that takes an object and an IntPtr that is used internally by the compiler during
            // code generation.  We have to create a dummy constructor that will allow a MethodRef to be passed to it, in order
            // to make the C# syntax work when resolving.
            TypeRef         delegateTypeRef = CreateRef();
            ConstructorDecl constructor     = new ConstructorDecl(new[] { new ParameterDecl(DelegateConstructorParameterName, delegateTypeRef) })
            {
                IsGenerated = true
            };

            Add(constructor);
        }