动态连接具有不同可能构造函数的类

时间:2011-06-01 20:14:30

标签: c# .net reflection constructor instantiation

假设我有两个看起来像这样的类:

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)存在哪个构造函数签名,以便我可以在运行时挂钩相应的方法?

注意:如果我很蠢,并且做错了,我也想知道。

3 个答案:

答案 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,我建议找到一个更好的解决方案。反射是一种强大的工具,使用它会带来复杂性;如果存在不太复杂的解决方案(例如工厂模式),那将是更可取的。您解决此特定问题的需求也可能反映出现有设计中的过度复杂性。如果您简化原始设计,您可能会发现技术问题消失了。