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

C# - rewrite delegate calls to Action<>

我需要用代码包装一些函数,这些代码将为这些函数预处理输入数据 ("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);
        }
    }
}

你能帮我改一下这个代码吗?

Action 的用法不同于 delegate:

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

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

我不确定我是否完全理解你想要做什么,我明白了吗?

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));

Action 后面有菱形符号 (<>),表示它是泛型。与 delegate 不同,它包含编译器使其类型安全所需的一切。这与 delegate 不同,后者在您定义特定委托之前并不是真正类型化的,它告诉编译器所有参数的类型。使用 Action 你只需要将类型放入钻石中,瞧,它现在是一个完整的类型。

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

public static void Wrapper(Action<ClientContext, SPRemoteEventProperties> f, ClientContext clientContext, SPRemoteEventProperties properties)
{

这就是编译器需要知道的关于该参数中将包含什么的所有信息,type-wise。