如何序列化指向被覆盖的虚拟方法的基础的委托?

Jef*_*tin 5 .net reflection serialization delegates compact-framework

虽然其他 问题有关使用反射来绕过所有安全装置,直接调用基类的实现的覆盖方法一般都遭到了嘲笑,并呼吁重新设计有问题的代码,我想我已经在一个奇异的,但合法的使用情况下跌跌撞撞:委托序列化.由于我已经看到了其他问题,不要用重新设计我的代码并停止尝试绕过类型系统的建议来轰炸我 - 我正在编写一个序列化格式化程序,而那些已经得到了忽略构造函数的传递.

令我沮丧的是,即使是v2.0 BCL也BinaryFormatter未能通过这个简单的NUnit测试:

[TestFixture]
public class DelegateSerializationTestFixture
{
    [Test]
    public void DelegateSerializationTest()
    {
        var bigKitty = new Lion();
        var kittyNoise = bigKitty.GetKittyNoiseFunc();

        Assert.AreEqual("Meow", kittyNoise());

        var stream = new MemoryStream();
        var formatter = new BinaryFormatter();
        formatter.Serialize(stream, kittyNoise);
        stream.Position = 0;
        formatter = new BinaryFormatter();
        var kittyNoise2 = (Func<string>)formatter.Deserialize(stream);

        Assert.AreEqual("Meow", kittyNoise2()); // returns Grrr
    }
}

[Serializable]
public class Lion : Cat
{
    public override string GetNoise()
    {
        return "Grrr";
    }

    public Func<string> GetKittyNoiseFunc()
    {
        return base.GetNoise;
    }
}

[Serializable]
public class Cat
{
    public virtual string GetNoise()
    {
        return "Meow";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果BinaryFormatter它本身无法做到这一点,我想我自己的Compact Framework 3.5二进制序列化实现也不会让人感到惊讶.

如果仅仅使用Compact Framework v3.5的有限反射功能来重建这样的委托真的是不可能的 - 而且很可能 - 是否有办法至少检测到这样的委托,以便我的序列化程序可以抛出而不是留下错误流中的数据?

到目前为止,我知道在序列化时检测此条件的唯一方法是使用完全信任反射来比较原始委托中的私有方法指针值与使用其公开可见属性重建委托所获得的值.