114
votes

Compiled with VS 2012, with project type WP 8.0 the following code will fail if debugger is not attached.

Somehow, if debugger not attached, compiler optimizations ruins the code inside Crash() - see comments in code.

Tested on Lumia 1520 (8.1) and Lumia 630 (8.0).

Any ideas why this is occurring?

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
        Button.Tap += (sender, args) => new A<B, string>(new B(), "string").Crash();
    }
}
public class B
{
    public void Foo<T>(T val) { }
}
public class A<T1, T2> where T1 : B
{
    private T1 _t1;
    private T2 _t2;
    public A(T1 t1, T2 t2)
    {
        _t2 = t2;
        _t1 = t1;
    }
    public void Crash()
    {
        var obs = Observable.Return(_t2);
        obs.Subscribe(result =>
        {
            //CLR is expecting T2 to be System.String here,
            //but somehow, after passing through Observable
            //T2 here is not a string, it's A<T1, T2>

            new List<T2>().Add(result);
        });
        //Will run normally if commented
        _t1.Foo(new object());
    }
}
1
Seems like a compiler bug, not an Rx bug. Have you tried using ILSpy or .NET Reflector to examine the generated IL? - Brandon
I would try using Observable.Return<T2>(_t2);, rather than leaving it up to the compiler to decide the type here. There might be a bug with that. Granted, that's a long shot. - cwharris
I've had a ton of problems with Rx on Windows Phone. For me, it would compile, then throw a MethodNotFoundException when I actually tried to call the containing class. For me, upgrading to the release version of VS Update 2 worked. I still have no idea what was actually wrong, but make sure you're using the latest updates on everything. Obviously our problems are a little different, but that might help lend some guidance. - Matthew Haugen
What is the question - 'any ideas?' - do you just want to know how to get it to stop crashing? - Tim Lovell-Smith
may be because _t1.Foo<missing type here>(and here too); - akbar ali

1 Answers

1
votes
 _t1.Foo<type>(type);

You are missing the type declaration. The compiler is guessing (and guessing wrong). Strictly type everything and it should run.