C# - 重写委托调用Action<>

时间:2018-03-14 07:58:48

标签: c# lambda delegates anonymous-function

我需要使用代码来包装许多函数,这些代码将预处理这些函数的输入数据(" Wrapper")。这是使用代理编写的代码(代码尽可能简化,但仍然可以正常运行并且可以立即编译):

namespace ConsoleApp
{
    class ClientContext
    {
        public int i = 1;
    }

    class SPRemoteEventProperties
    {
    }

    class Program
    {
        public delegate void Del(ClientContext clientContext, SPRemoteEventProperties properties);

        public static void Wrapper(Del f, ClientContext clientContext, SPRemoteEventProperties properties)
        {
            ClientContext newClientContext = new ClientContext
            {
                i = clientContext.i * 2
            };

            f(newClientContext, properties);
        }

        static void Main(string[] args)
        {
            Function1(new ClientContext(), new SPRemoteEventProperties());
            Function2(new ClientContext(), new SPRemoteEventProperties());

            Wrapper(Function1, new ClientContext(), new SPRemoteEventProperties());
            Wrapper(Function2, new ClientContext(), new SPRemoteEventProperties());

            Console.Read();
        }

        static void Function1(ClientContext clientContext, SPRemoteEventProperties properties)
        {
            Console.WriteLine("Function1: " + clientContext.i);
        }

        static void Function2(ClientContext clientContext, SPRemoteEventProperties properties)
        {
            Console.WriteLine("Function2: " + clientContext.i);
        }
    }
}

现在,为了简化代码,我想使用Action<>重写代码。语法和内联函数'码。这就是我尝试做的事情,但我无法编写正确且有效的程序:

using System;

namespace ConsoleApp
{
    class ClientContext
    {
        public int i = 1;
    }

    class SPRemoteEventProperties
    {
    }

    class Program
    {
        Action<ClientContext, SPRemoteEventProperties> Act;

        // error in next line =>
        public static void Wrapper(Act f, ClientContext clientContext, SPRemoteEventProperties properties)
        {
            ClientContext newClientContext = new ClientContext
            {
                i = clientContext.i * 2
            };

            f(newClientContext, properties);
        }

        static void Main(string[] args)
        {
            Function1(new ClientContext(), new SPRemoteEventProperties());
            Function2(new ClientContext(), new SPRemoteEventProperties());

            // error in next 2 lines =>
            Wrapper((new ClientContext(), new SPRemoteEventProperties()) => Console.WriteLine("Function1: " + clientContext.i));
            Wrapper((new ClientContext(), new SPRemoteEventProperties()) => Console.WriteLine("Function2: " + clientContext.i));

            Console.Read();
        }

        static void Function1(ClientContext clientContext, SPRemoteEventProperties properties)
        {
            Console.WriteLine("Function1: " + clientContext.i);
        }

        static void Function2(ClientContext clientContext, SPRemoteEventProperties properties)
        {
            Console.WriteLine("Function2: " + clientContext.i);
        }
    }
}

你能帮我纠正这段代码吗?

3 个答案:

答案 0 :(得分:1)

Action的使用情况与delegate

不同

虽然delegate语法定义了可用于定义变量的类型声明,但Action语法已经是类型,您可以使用它来创建变量。
我不确定我是否清楚,但是,以下是正确使用的语法:

 public static void Wrapper(Action<ClientContext, SPRemoteEventProperties> f, ClientCo ...

答案 1 :(得分:1)

我不确定我完全明白你要做什么,我是否接近?

public static void Wrapper(ClientContext clientContext, SPRemoteEventProperties properties, Action<ClientContext, SPRemoteEventProperties> action)
{
    action(newClientContext, properties);
}

...
Wrapper( new ClientContext(), new SPRemoteEventProperties(),(context, properties) => Console.WriteLine("Function1: " + context.i));

答案 2 :(得分:1)

Action后面有钻石符号(<>),这表示它是泛型类型。与delegate不同,它包含编译器使其类型安全所需的所有内容。这与delegate不同,Action在您定义特定委托之前并未真正输入,该委托告诉编译器所有参数的类型。使用public static void Wrapper(Action<ClientContext, SPRemoteEventProperties> f, ClientContext clientContext, SPRemoteEventProperties properties) { ,你只需要将类型放入钻石中,现在它就是一个完整的类型。

由于参数名称始终以其类型开头,因此原型应如下所示:

{{1}}

这就是编译器需要知道的关于该参数中包含的内容的所有内容,类型。