using System;
using System.Collections.Generic;
using Chernobyl.Event;
using Chernobyl.Utility;
namespace Chernobyl.Values
{
///
/// An that allows you to select a value (the result)
/// from another (the source) and keep it up to date
/// even if the source value changes.
///
/// The type held within the
/// being used as the source.
/// The type held within this
/// or the result.
public class Select : HeldValue
{
///
/// Initializes a new instance of the
/// class.
///
/// The to select the result
/// value from.
/// The method to use to select the result value
/// from .
public Select(IValue source, Func selector)
: this(source, selector, EqualityComparer.Default)
{}
///
/// Initializes a new instance of the
/// class.
///
/// The to select the result
/// value from.
/// The method to use to select the result value
/// from .
/// The instance used to compare new and previous
/// values of to determine if
/// should be raised.
public Select(IValue source, Func selector,
IEqualityComparer comparer)
: base(default(TResult), comparer)
{
source.ThrowIfNull("source");
selector.ThrowIfNull("selector");
_source = source;
_selector = selector;
_source.Provide += OnSourceProvide;
}
///
/// An event handler that is invoked when the value contained within
/// changes. This method ensures the result value
/// contained within this stays up-to-date.
///
/// The sender of the event.
/// The arguments containing information about the change.
void OnSourceProvide(object sender, ValueChangedEventArgs e)
{
Value = _selector(e.NewValue);
}
///
/// The to select the result value from.
///
readonly IValue _source;
///
/// The method to use to select the result value from .
///
readonly Func _selector;
}
///
/// Utility methods and extensions for .
///
public static class SelectExtensions
{
///
/// Creates an capable of selecting a result
/// value from another and keeping the result
/// up to date.
///
/// The type held within the
/// being used as the source.
/// The type held within the returned
/// or the result.
/// The to select the result
/// value from.
/// The method to use to select the result value
/// from .
/// The instance that contains the selected result and keeps
/// that result up to date.
public static IValue Select(this IValue source,
Func selector)
{
return new Select(source, selector);
}
}
}