C# 传递任何方法作为参数 [英] C# Pass any method as parameter

查看:50
本文介绍了C# 传递任何方法作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个网络应用程序,我想在其中实现强类型 RPC.因此,无论参数如何,我都希望能够传递方法,这样我就可以获取它们并将它们存储在字典中,以便在数据包到达后我也可以正确构造请求参数我能够使用参数读取它使用相同的远程方法

I'm making a networking application where I want to implement strongly typed RPC. As result I'd like to be able to pass methods no matter the parameters so I can get them and store them in a dictionary so I can construct request parameters properly as well once a packet arrive I am able to read it using the parameters the same remote method used

我想要这样的东西:

Register(Enum key, [method with unknown parameters])

推荐答案

在使用泛型和委托约束的 C# 8.0 中,您可以执行以下操作:

In C# 8.0 using generics and Delegate Constraint you can do something like this:

using System;
using System.Collections.Generic;

namespace ConsoleApp
{

    public class Program
    {
        public static void Main(params string[] args)
        {
            var app = new NetworkingApplication();
            app.Register<Action<int, string>>(PacketType.Type1, Method1, 1, "string1 argument");
            app.Register<Func<string, string>>(PacketType.Type2, Method2, "string2 argument");
            app.OnPacketReceived(PacketType.Type1);
            app.OnPacketReceived(PacketType.Type2);
        }

        public static void Method1(int arg1, string arg2)
        {
            Console.WriteLine($"Method1 Invoked with args: {arg1}, {arg2}");
        }

        public static string Method2(string arg1)
        {
            Console.WriteLine($"Method2 Invoked with args: {arg1}");
            return "Foo";
        }
    }

    public class NetworkingApplication
    {
        private readonly IDictionary<PacketType, DelegateInvoker> _registrations;

        public NetworkingApplication()
        {
            _registrations = new Dictionary<PacketType, DelegateInvoker>();
        }

        public void Register<TDelegate>(PacketType packetType, TDelegate @delegate, params object[] args)
            where TDelegate : Delegate
        {
            _registrations[packetType] = new DelegateInvoker(@delegate, args);
        }

        //invoke this when the packet is received
        public void OnPacketReceived(PacketType type)
        {
            if (_registrations.TryGetValue(type, out var invoker))
            {
                invoker.Invoke();
            }
        }

        private class DelegateInvoker
        {
            public DelegateInvoker(Delegate @delegate, object[] args)
            {
                Delegate = @delegate;
                Arguments = args;
            }

            private Delegate Delegate { get; }
            private object[] Arguments { get; }

            public void Invoke()
            {
                Delegate.Method.Invoke(Delegate.Target, Arguments);
            }
        }
    }





    public enum PacketType
    {
        Type1,
        Type2,
        Type3
    }
}

这篇关于C# 传递任何方法作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆