虽然其他 关于使用反射绕过所有安全措施并直接调用基类的重写方法实现的其他问题通常遭到嘲笑和要求重新设计有问题的代码,但我想我偶然发现了一个奇怪但合法的用例:delegate序列化。由于我已经看到了其他问题,请不要轰炸我重新设计我的代码并停止尝试绕过类型系统的建议——我正在编写一个序列化格式化程序,而那些已经获得了忽略构造函数的通行证。
令我沮丧的是,即使是 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";
}
}
如果BinaryFormatter
它自己不能做到这一点,我想我自己的 Compact Framework 3.5 二进制序列化实现也丢球了,我不应该感到惊讶。
如果真的不可能仅使用 Compact Framework v3.5 的有限反射功能来重构这样的委托——而且很可能——有没有办法至少检测到这样的委托,以便我的序列化程序可以抛出而不是留下不正确的流中的数据?
到目前为止,我知道在序列化时检测这种情况的唯一方法是使用完全信任反射将原始委托中的私有方法指针值与我使用其公开可见的属性重建委托所获得的值进行比较。