我有这个代表:
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;
}
}
我想根据给定的IEnumerable<Tuple<PacketHandlerAttribute, PacketHandler>>
值创建一个返回ServerType
的方法。因此,如果我使用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缩短这一点?
答案 0 :(得分:2)
我觉得这是有帮助的。
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)));
}