Как сериализовать делегат, указывающий на базу переопределенного виртуального метода?

Хотя другиевопросыоб использовании отражения для обхода всех мер безопасности и прямого вызова реализации базового класса переопределенного метода, как правило, встречались с насмешками и призывами перепроектировать нарушающий код, я думаю, что наткнулся на странный, но законный вариант использования: делегировать сериализацию. Поскольку я видел другие вопросы, пожалуйстане забрасывайте меня советами переделать мой код и перестать пытаться обойти систему типов -- я пишу средство форматирования сериализации, а те уже получили возможность игнорировать конструкторы.

К моему большому разочарованию, даже 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 ограниченные возможности отражения — и это вполне может быть — есть ли способ хотя бы обнаружить такого делегата, чтобы мой сериализатор мог выбрасывать вместо того, чтобы оставлять неверные данные в потоке?

До сих пор единственным известным мне способом обнаружения этого условия во время сериализации является использование отражения с полным доверием для сравнения значения частного указателя метода в исходном делегате со значением, которое я получаю от восстановления делегата с использованием его общедоступного видимые свойства.

5
задан Community 23 May 2017 в 12:11
поделиться