Bug de extensões reativas no Windows Phone

114

Compilado com VS 2012, com tipo de projeto, WP 8.0o código a seguir falhará se o depurador não estiver anexado.

De alguma forma, se o depurador não estiver conectado, as otimizações do compilador estragam o código interno Crash()- consulte os comentários no código.

Testado no Lumia 1520 (8.1) e Lumia 630 (8.0) .

Alguma ideia de por que isso está ocorrendo?

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());
    }
}
Yuriy Naydenov
fonte
6
Parece um bug do compilador, não um bug Rx. Você tentou usar ILSpy ou .NET Reflector para examinar o IL gerado?
Brandon
8
Eu tentaria usar Observable.Return<T2>(_t2);, em vez de deixar para o compilador decidir o tipo aqui. Pode haver um bug com isso. Concedido, isso é um tiro no escuro.
cwharris
6
Tive muitos problemas com Rx no Windows Phone. Para mim, ele compilaria e, em seguida, geraria um MethodNotFoundExceptionquando eu realmente tentasse chamar a classe contida. Para mim, a atualização para a versão de lançamento do VS Update 2 funcionou. Ainda não tenho ideia do que estava realmente errado, mas certifique-se de usar as atualizações mais recentes em tudo. Obviamente, nossos problemas são um pouco diferentes, mas isso pode ajudar a nos dar alguma orientação.
Matthew Haugen
5
Qual é a pergunta - 'alguma ideia?' - você só quer saber como fazer com que ele pare de travar?
Tim Lovell-Smith
1
pode ser porque _t1.Foo <tipo ausente aqui> (e aqui também);
akbar ali

Respostas:

1
 _t1.Foo<type>(type);

Está faltando a declaração de tipo. O compilador está adivinhando (e adivinhando errado). Digite tudo estritamente e ele deve ser executado.

Japes
fonte
Isso não é uma pista, você pode implementar IObserver e IObservable por conta própria e tudo funcionará bem.
Yuriy Naydenov
Parece que o depurador está criando uma conexão com o compilador, e o depurador também precisa que todos os vars sejam digitados estritamente. O depurador está supondo correto, e o compilador de alguma forma está pegando ques dele. Realmente não importa por que o depurador corrige o problema, a causa raiz foi encontrada.
Japes de