Хотя другиевопросыоб использовании отражения для обхода всех мер безопасности и прямого вызова реализации базового класса переопределенного метода, как правило, встречались с насмешками и призывами перепроектировать нарушающий код, я думаю, что наткнулся на странный, но законный вариант использования: делегировать сериализацию. Поскольку я видел другие вопросы, пожалуйстане забрасывайте меня советами переделать мой код и перестать пытаться обойти систему типов -- я пишу средство форматирования сериализации, а те уже получили возможность игнорировать конструкторы.
К моему большому разочарованию, даже BCL v2.0BinaryFormatter
не проходит этот простой тест 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)formatter.Deserialize(stream);
Assert.AreEqual("Meow", kittyNoise2()); // returns Grrr
}
}
[Serializable]
public class Lion : Cat
{
public override string GetNoise()
{
return "Grrr";
}
public Func GetKittyNoiseFunc()
{
return base.GetNoise;
}
}
[Serializable]
public class Cat
{
public virtual string GetNoise()
{
return "Meow";
}
}
Если BinaryFormatter
сам не может сделать это правильно, я думаю, Не удивляйтесь, что моя собственная реализация бинарной сериализации Compact Framework 3.5 тоже не справляется.
Если действительно невозможно воссоздать такой делегат, используя только Compact Framework v3.5 ограниченные возможности отражения — и это вполне может быть — есть ли способ хотя бы обнаружить такого делегата, чтобы мой сериализатор мог выбрасывать вместо того, чтобы оставлять неверные данные в потоке?
До сих пор единственным известным мне способом обнаружения этого условия во время сериализации является использование отражения с полным доверием для сравнения значения частного указателя метода в исходном делегате со значением, которое я получаю от восстановления делегата с использованием его общедоступного видимые свойства.