【问题标题】:C# - rewrite delegate calls to Action<>C# - 重写对 Action<> 的委托调用
【发布时间】:2018-03-14 07:58:48
【问题描述】:

我需要用可以预处理这些函数的输入数据的代码(“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);
        }
    }
}

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

【问题讨论】:

  • 尝试在Wrapper 参数中传递Action&lt;ClientContext, SPRemoteEventProperties&gt; f 而不是Act f
  • 您正在将一种委托类型替换为另一种。以前的委托类型是Del。新的委托类型是Action&lt;ClientContext, SPRemoteEventProperties&gt;。因此,只需将一种用法替换为另一种(您只在一个地方使用它),然后删除 Del 类型,因为它不再需要了。
  • Action&lt;ClientContext, SPRemoteEventProperties&gt; Act; 不是类型定义。但是您确实尝试使用它。
  • Action f ... 作为 Wrapper 的第一个参数解决了第一个错误。

标签: c# lambda delegates anonymous-function


【解决方案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】:

Action 的用法与delegate 不同:

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

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

【讨论】:

    【解决方案3】:

    Action 后面有菱形符号 (&lt;&gt;),这表明它是泛型类型。与delegate 不同,它包含编译器使其类型安全所需的一切。这与delegate 不同,delegate 在定义特定委托之前不会真正输入,它会告诉编译器所有参数的类型。使用Action,您只需将类型放入菱形中,瞧,它现在是一个完整的类型。

    由于参数名称总是以它的类型开头,你的原型应该是这样的:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多