Ошибка реактивных расширений на Windows Phone

114

Скомпилированный VS 2012с типом проекта WP 8.0следующий код завершится ошибкой, если отладчик не подключен.

Каким-то образом, если отладчик не подключен, оптимизация компилятора разрушает код внутри Crash()- см. Комментарии в коде.

Проверено на Lumia 1520 (8.1) и Lumia 630 (8.0) .

Есть идеи, почему это происходит?

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());
    }
}
Юрий Найденов
источник
6
Похоже на ошибку компилятора, а не на ошибку Rx. Вы пробовали использовать ILSpy или .NET Reflector для проверки сгенерированного IL?
Brandon
8
Я бы попробовал использовать Observable.Return<T2>(_t2);, а не оставлял компилятору решать тип здесь. В этом может быть ошибка. Конечно, это долгий путь.
cwharris
6
У меня была масса проблем с Rx на Windows Phone. Для меня он компилировался, а затем генерировал, MethodNotFoundExceptionкогда я действительно пытался вызвать содержащий класс. Для меня сработало обновление до окончательной версии VS Update 2. Я до сих пор понятия не имею, что было на самом деле не так, но убедитесь, что вы используете последние обновления для всего. Очевидно, что наши проблемы немного отличаются, но это может помочь нам в этом.
Matthew Haugen
5
В чем вопрос - какие идеи? - вы просто хотите знать, как заставить его перестать падать?
Тим Ловелл-Смит,
1
может быть потому, что _t1.Foo <отсутствует тип здесь> (и здесь тоже);
Акбар Али

Ответы:

1
 _t1.Foo<type>(type);

Вам не хватает объявления типа. Компилятор угадывает (и угадывает неправильно). Строго все набирайте и должно запуститься.

Japes
источник
Это не ключ к разгадке, вы можете реализовать IObserver и IObservable самостоятельно, и все будет работать нормально.
Юрий Найденов
Похоже, что отладчик создает соединение с компилятором, и отладчику также необходимо, чтобы все переменные были строго типизированы. Отладчик угадывает правильно, а компилятор каким-то образом берет от него вопросы. На самом деле не имеет значения, почему отладчик устраняет проблему, основная причина найдена.
Japes