English 中文(简体)
如何将代表编订成一个压倒性虚拟方法的基础?
原标题:How to serialize a delegate that points to the base of an overridden virtual method?

While other questions about using reflection to bypass all safeties and directly call the base class s implementation of an overridden method have generally been met with derision and calls to redesign the offending code, I think I ve stumbled upon a bizarre but legitimate use case: delegate serialization. Since I ve seen the other questions, please don t bombard me with advice to redesign my code and stop trying to bypass the type system -- I m writing a serialization formatter, and those already get a pass to ignore constructors.

Much to my dismay, even the v2.0 BCL s BinaryFormatter fails this simple NUnit test:

[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";
    }
}

http://www.ohchr.org。 我怀疑,我不感到惊讶的是,我自己的《契约框架》3.5 双周期化的实施也减少了球。

如果仅仅利用《契约框架》第3.5条反映能力有限——真正不可能重建这种代表————至少可以发现这种代表,以便我的序列者能够放弃不正确的数据?

So far, the only way I know of to detect this condition at serialization time is to use full-trust reflection to compare the private method-pointer value in the original delegate with the value I get from reconstructing the delegate using its publicly visible properties.

问题回答

问题。 页: 1 检测方式的黑体:使用公共财产制作复制件,检查与原始财产平等。 显示其工作的样本:

using System;
using System.Linq;
using System.IO;

class Base
{
    public virtual void Foo()
    {
        Console.WriteLine("Base");
    }
}

class Derived : Base
{
    public override void Foo()
    {
        Console.WriteLine("Derived");
    }

    public Action NonVirtualAction { get { return base.Foo; } }
    public Action VirtualAction { get { return Foo; } }
}

class Program
{
    static void Main()
    {
        var derived = new Derived();
        var virtualAction = derived.VirtualAction;
        var nonVirtualAction = derived.NonVirtualAction;

        var virtualCopy = CreateCopy(virtualAction);
        var nonVirtualCopy = CreateCopy(nonVirtualAction);

        Console.WriteLine(virtualCopy.Equals(virtualAction)); // True
        Console.WriteLine(nonVirtualCopy.Equals(nonVirtualAction)); // False
    }

    static Delegate CreateCopy(Delegate del)
    {
        // TODO: Validate it s not multi-cast
        return Delegate.CreateDelegate(del.GetType(), del.Target, del.Method);
    }
}

我不知道你是如何实际做到的create,尽管......或者还有其他情况,这种“复制品的质量”会给错。





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签