Miista / pose

Replace any .NET method (including static and non-virtual) with a delegate
MIT License
27 stars 3 forks source link

Cannot shim constructor for value type #39

Open Miista opened 10 months ago

Miista commented 10 months ago

This is evident if attempting the following:

Shim.Replace(() => new DateTime()).With(() => new DateTime(2004, 1, 1));

The above is simply the default constructor. However, GetMethodFromExpression cannot find the constructor for said constructor. It fails in the validation phase because the original method to shim (the constructor) is null. I suspect this is due to it being the default constructor because the following works--insofar as it passes the validation phase.

Shim
    .Replace(() => new DateTime(Is.A<int>(), Is.A<int>(), Is.A<int>()))
    .With((int y, int m, int d) => new DateTime(2004, 1, 1));

The above is no longer the default constructor, and GetMethodFromExpression successfully finds the intended constructor. During the isolation, I can also see that the breakpoint in the replacement is called as expected. However, the replacement value is never actually present in the resulting code. See the following example.

var s = Shim
    .Replace(() => new DateTime(Is.A<int>(), Is.A<int>(), Is.A<int>()))
    .With((int y, int m, int d) => new DateTime(2004, 1, 1));

    var dateTimeShim = Shim.Replace(() => DateTime.Now).With(() => new DateTime(2004, 1, 1));

    PoseContext.Isolate(()=>
    {
        var dt = new DateTime(2023, 1, 1);
        Console.WriteLine(dt); // <-- This prints '01-01-0001 00:00:00'
    }, s);
Miista commented 10 months ago

I've explicitly not labelled this as a bug since I don't know whether this is due to a limitation in the CLR.