繁体   English   中英

使用反射获取具有特定属性值的方法

[英]Using reflection to get methods with certain attribute value

我有这个代表:

 public delegate void PacketHandler(Client client, Packet packet);

我有这个属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class PacketHandlerAttribute : Attribute
{
    public ServerType Server { get; private set; }
    public int Code { get; private set; }

    public PacketHandlerAttribute(ServerType server, int code)
    {
        this.Server = server;
        this.Code = code;
    }
}

我想根据给定的ServerType值创建一个方法来返回IEnumerable<Tuple<PacketHandlerAttribute, PacketHandler>> 因此,如果我使用ServerType.Server调用此方法,它将返回所有包含Server1作为其属性的方法。

到目前为止,我做到了:

public static IEnumerable<Doublet<PacketHandlerAttribute, PacketHandler>> GetPacketHandlers(ServerType server)
    {
        foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
        {
            foreach (MethodInfo method in type.GetMethods())
            {
                PacketHandlerAttribute attribute = (PacketHandlerAttribute)method.GetCustomAttribute(typeof(PacketHandlerAttribute));

                if (attribute != null)
                {
                    if (attribute.Server == server)
                    {
                        yield return new Doublet<PacketHandlerAttribute, PacketHandler>(attribute, (PacketHandler)Delegate.CreateDelegate(typeof(PacketHandler), method));
                    }
                }
            }
        }
    }

我想问一下这是否是正确的方法,而LINQ如何缩短它呢?

我认为这会有所帮助。

 var methods = from type in assembly.GetTypes()
                      from method in type.GetMethods()
                      let attribute = method.GetCustomAttributes(typeof(PacketHandlerAttribute), false).Cast<PacketHandlerAttribute>().FirstOrDefault()
                      where attribute?.Code == 1
                      select new { method, attribute };

你的方法

public IEnumerable<(PacketHandlerAttribute attribute, PacketHandler handler)> GetPacketHandlers(ServerType server)
        {
            var assembly = Assembly.GetEntryAssembly();

            return from type in assembly.GetTypes()
                          from method in type.GetMethods()
                          let attribute = method.GetCustomAttributes(typeof(PacketHandlerAttribute), false).Cast<PacketHandlerAttribute>().FirstOrDefault()
                          where attribute?.Server == server
                          select (attribute, (PacketHandler)method.CreateDelegate(typeof(PacketHandler)));
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM