リフレクションを使用してすべての安全性をバイパスし、オーバーライドされたメソッドの基本クラスの実装を直接呼び出すことに関する他の 質問は、一般的に、問題のあるコードを再設計するための嘲笑と呼び出しに遭遇しましたが、奇妙ではあるが正当なユースケースに出くわしたと思います:デリゲート連載。他の質問を見たので、コードを再設計し、型システムをバイパスしようとするのをやめるというアドバイスで私を攻撃しないでください-私はシリアライゼーションフォーマッターを書いていますが、それらはすでにコンストラクターを無視するパスを取得しています。
残念なことに、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 の制限されたリフレクション機能のみを使用してそのようなデリゲートを再構築することが本当に不可能である場合 (そうかもしれません)、少なくともそのようなデリゲートを検出して、シリアライザーが正しくないままにする代わりにスローできるようにする方法はありますか?ストリーム内のデータ?
これまでのところ、シリアル化時にこの状態を検出する唯一の方法は、完全信頼のリフレクションを使用して、元のデリゲートのプライベート メソッド ポインターの値と、公開されているプロパティを使用してデリゲートを再構築して得た値を比較することです。