Repository: AvaloniaUI/Avalonia
File: src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin.cs (C#)

Code before:
﻿// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.

using System;

namespace Avalonia.Data.Core.Plugins
{
    /// <summary>
    /// Handles binding to <see cref="IObservable{T}"/>s for the '^' stream binding operator.
    /// </summary>
    public class ObservableStreamPlugin : IStreamPlugin
    {
        /// <summary>
        /// Checks whether this plugin handles the specified value.
        /// </summary>
        /// <param name="reference">A weak reference to the value.</param>
        /// <returns>True if the plugin can handle the value; otherwise false.</returns>
        public virtual bool Match(WeakReference reference) => reference.Target is IObservable<object>;

        /// <summary>
        /// Starts producing output based on the specified value.
        /// </summary>
        /// <param name="reference">A weak reference to the object.</param>
        /// <returns>
        /// An observable that produces the output for the value.
        /// </returns>
        public virtual IObservable<object> Start(WeakReference reference)
        {
            return reference.Target as IObservable<object>;
        }
    }
}


Review comment (bug):
`Target` can return null. I'd use `WeakReference<object>` which prevents the race condition by introducing a Try method.

Code after:
﻿// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.

using System;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection;

namespace Avalonia.Data.Core.Plugins
{
    /// <summary>
    /// Handles binding to <see cref="IObservable{T}"/>s for the '^' stream binding operator.
    /// </summary>
    public class ObservableStreamPlugin : IStreamPlugin
    {
        static MethodInfo observableSelect;

        /// <summary>
        /// Checks whether this plugin handles the specified value.
        /// </summary>
        /// <param name="reference">A weak reference to the value.</param>
        /// <returns>True if the plugin can handle the value; otherwise false.</returns>
        public virtual bool Match(WeakReference reference)
        {
            return reference.Target.GetType().GetInterfaces().Any(x =>
              x.IsGenericType &&
              x.GetGenericTypeDefinition() == typeof(IObservable<>));
        }

        /// <summary>
        /// Starts producing output based on the specified value.
        /// </summary>
        /// <param name="reference">A weak reference to the object.</param>
        /// <returns>
        /// An observable that produces the output for the value.
        /// </returns>
        public virtual IObservable<object> Start(WeakReference reference)
        {
            var target = reference.Target;

            // If the observable returns a reference type then we can cast it.
            if (target is IObservable<object> result)
            {
                return result;
            };

            // If the observable returns a value type then we need to call Observable.Select on it.
            // First get the type of T in `IObservable<T>`.
            var sourceType = reference.Target.GetType().GetInterfaces().First(x =>
                  x.IsGenericType &&