C# 以前在旧计算机上工作的ReactiveExtension现在失败了

C# 以前在旧计算机上工作的ReactiveExtension现在失败了,c#,system.reactive,C#,System.reactive,我正在使用中的代码来处理对可观察集合的监视更改。代码已经运行了几个月,没有任何问题。我最近更新了一台新电脑。在完成所有设置并从存储库中取出代码后,我遇到了一个奇怪的问题。代码不再有效 下面是我代码的相关部分,所有这些都发生在构造函数中: public class PurchaseOrderReceipt : BaseEntity { /// <summary> /// Initializes a new instance of the <see cre

我正在使用中的代码来处理对可观察集合的监视更改。代码已经运行了几个月,没有任何问题。我最近更新了一台新电脑。在完成所有设置并从存储库中取出代码后,我遇到了一个奇怪的问题。代码不再有效

下面是我代码的相关部分,所有这些都发生在构造函数中:

 public class PurchaseOrderReceipt : BaseEntity
{
    /// <summary>
    ///     Initializes a new instance of the <see cref="PurchaseOrderReceipt" /> class.
    /// </summary>
    public PurchaseOrderReceipt()
    {
        this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
        this.DateReceived = DateTime.Now;

        this.ReceiptItems.ObserveCollectionChanged()
            .SubscribeWeakly(this, (target, eventArgs) => target.ReceiptItemsChanged());
    }
公共类PurchaseOrderReceive:BaseEntity
{
/// 
///初始化类的新实例。
/// 
公共采购订单收据()
{
this.ReceiptItems=新的ObservableCollection();
this.DateReceived=DateTime.Now;
this.ReceiptItems.ObserveCollectionChanged()
.subscribeWelly(this,(target,eventArgs)=>target.ReceiptItemsChanged());
}
在SubscribeException行上引发异常,并显示以下错误消息:ArgumentException:onNext必须引用静态方法,否则订阅仍将保留对目标的强引用

我可以通过创建PurchaseOrderReceive的实例在LinqPad中重新创建问题

更奇怪的是,如果我在LinqPad中编写一个简单的类来镜像PurchaseOrderReceive类中的设置,那么它就不能正常工作了

LinqPad代码:

void Main()
{
    var x = new Test(); 
    x.ReceiptItems.Add(new PurchaseOrderItemReceipt());

}

public class Test:BaseEntity
{
    public ObservableCollection<PurchaseOrderItemReceipt> ReceiptItems {get; set;}

    public Test()
    {
        this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
        this.ReceiptItems.ObserveCollectionChanged().SubscribeWeakly(this,(target, eventargs) => target.TestChanged());
    }

    private void TestChanged()
    {
        "Changed!".Dump();
    }
}
void Main()
{
var x=新测试();
x、 添加(新的PurchaseOrderItemReceipt());
}
公共类测试:BaseEntity
{
公共ObservableCollection ReceiptItems{get;set;}
公开考试()
{
this.ReceiptItems=新的ObservableCollection();
this.ReceiptItems.ObserveCollectionChanged().SubscribeWelly(this,(target,eventargs)=>target.TestChanged());
}
私有void TestChanged()
{
“已更改!”.Dump();
}
}
已更改!将在结果窗口中打印出来

下面是顶部链接中的CustomReactiveExtension类

public static class CustomReactiveExtension
    {
        public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> ObserveCollectionChanged(this INotifyCollectionChanged collection)
        {
            return Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                handler => (sender, e) => handler(sender, e),
                handler => collection.CollectionChanged += handler,
                handler => collection.CollectionChanged -= handler);
        }

        public static IDisposable SubscribeWeakly<T, TTarget>(this IObservable<T> observable, TTarget target, Action<TTarget, T> onNext) where TTarget : class
        {
            var reference = new WeakReference(target);

            if (onNext.Target != null)
            {
                throw new ArgumentException("onNext must refer to a static method, or else the subscription will still hold a strong reference to target");
            }

            IDisposable subscription = null;
            subscription = observable.Subscribe(item =>
            {
                var currentTarget = reference.Target as TTarget;
                if (currentTarget != null)
                {
                    onNext(currentTarget, item);
                }
                else
                {
                    subscription.Dispose();
                }
            });

            return subscription;
        }
    }
公共静态类CustomReactiveExtension
{
公共静态IObservable ObserveCollectionChanged(此INotifyCollectionChanged集合)
{
返回可观察的.FromEventPattern(
处理程序=>(发送方,e)=>处理程序(发送方,e),
handler=>collection.CollectionChanged+=handler,
handler=>collection.CollectionChanged-=handler);
}
public static IDisposable subscribeWelly(此IObservable observable,TTarget target,Action onNext),其中TTarget:class
{
var参考=新的WeakReference(目标);
如果(onNext.Target!=null)
{
抛出新ArgumentException(“onNext必须引用静态方法,否则订阅仍将保留对目标的强引用”);
}
IDisposable订阅=null;
订阅=可观察。订阅(项目=>
{
var currentTarget=reference.Target作为TTarget;
如果(currentTarget!=null)
{
onNext(当前目标,项目);
}
其他的
{
subscription.Dispose();
}
});
退订;
}
}

有什么想法吗?

我不是100%肯定,但我猜测是不同版本的编译器或不同的编译选项导致lambda被编译为实例方法,而不是静态方法

最简单的解决方案是显式实现一个静态方法,用作
onNext
回调,即:

private static void OnReceiptItemsChanged(PurchaseOrderReceipt target, 
    EventPattern<NotifyCollectionChangedEventArgs> eventPattern)
{
    // TODO Do something here
}

现在,无论您使用哪种编译器或使用哪种编译选项,回调都始终是一种静态方法。

非常有效!谢谢!
this.ReceiptItems.ObserveCollectionChanged().SubscribeWeakly(this, OnReceiptItemsChanged);