假设我有两个看起来像这样的类:
public class ByteFilter
{
private Func <int, byte[]> readBytes;
private Action<byte[]> writeBytes;
public ByteFilter(Func <int, byte[]> readBytes, Action<byte[]> writeBytes)
{
this.readBytes = readBytes;
this.writeBytes = writeBytes;
}
}
public class PacketFilter
{
private Func<Packet> readPacket;
private Action<Packet> writePacket;
Public PacketFilter(Func<Packet> readPacket, Action<Packet> writePacket)
{
this.readBytes = readPacket;
this.writeBytes = writePacket;
}
}
可以在运行时(通过Activator.CreateInstance
)实例化任一类以执行过滤功能。读取和写入方法将在运行时连接到其他类的方法,这些方法将提供和接受字节数组或数据包。
在每个过滤器中都有执行过滤功能的附加代码:
public void Process()
{
while (!done)
{
byte[] data = ReadBytes(); // or ReadPacket()
// perform filtering on data
WriteBytes(data); // or WritePacket()
}
}
如果每个过滤器中只有一个上述构造函数签名,我如何确定(使用Reflection)存在哪个构造函数签名,以便我可以在运行时挂钩相应的方法?
注意:如果我很蠢,并且做错了,我也想知道。
答案 0 :(得分:2)
你能做点什么吗?
bool packetConstructor =
typeof(PacketFilter).GetConstructors()
.Any(c => c.GetParameters()
.Any(p => p.ParameterType
== typeof(Func<Packet>)));
用适当的实例替换typeof(PacketFilter)
。
答案 1 :(得分:2)
未提及的选项是使用Fasterflect,这是一个创建的库,可以在可能的情况下更轻松,更快速地进行反射。
它还有一些基于核心反射功能构建的功能,其中之一就是当你不知道哪些构造函数可用时构造对象的能力。
var instance = typeof(PacketFilter).TryCreateInstance( new { Foo = "Bar" } );
传递命名值或离散名称和值数组的字典时也存在重载。最新的代码还提供了仅从有序值列表构造对象的扩展,并按类型匹配参数。
Fasterflect将自动选择具有最匹配参数的构造函数。如果它无法使用值,它将尝试在构造后设置匹配的属性。您可以选择要求使用所有值。
免责声明:我是该项目的撰稿人。
答案 2 :(得分:1)
您可以枚举构造函数(以获取一个构造函数),然后枚举构造函数的参数。由于参数应该是泛型类型,因此您需要枚举每个泛型构造函数参数的泛型类型参数。请注意,所有这些都是非常hacky,我建议找到一个更好的解决方案。反射是一种强大的工具,使用它会带来复杂性;如果存在不太复杂的解决方案(例如工厂模式),那将是更可取的。您解决此特定问题的需求也可能反映出现有设计中的过度复杂性。如果您简化原始设计,您可能会发现技术问题消失了。