IObserver<T> Interface
Definição
Fornece um mecanismo para receber notificações por push.Provides a mechanism for receiving push-based notifications.
generic <typename T>
public interface class IObserver
public interface IObserver<in T>
type IObserver<'T> = interface
Public Interface IObserver(Of In T)
Parâmetros de tipo
- T
O objeto que fornece informações de notificação.The object that provides notification information.
Este parâmetro de tipo é contravariante. Isso significa que é possível usar o tipo especificado ou qualquer tipo menos derivado. Para obter mais informações sobre covariância e contravariância, consulte Covariância e contravariância em genéricos.- Derivado
Exemplos
O exemplo a seguir ilustra o padrão de design do observador.The following example illustrates the observer design pattern. Ele define uma Location classe que contém informações de latitude e longitude.It defines a Location class that contains latitude and longitude information.
public struct Location
{
double lat, lon;
public Location(double latitude, double longitude)
{
this.lat = latitude;
this.lon = longitude;
}
public double Latitude
{ get { return this.lat; } }
public double Longitude
{ get { return this.lon; } }
}
Public Structure Location
Dim lat, lon As Double
Public Sub New(ByVal latitude As Double, ByVal longitude As Double)
Me.lat = latitude
Me.lon = longitude
End Sub
Public ReadOnly Property Latitude As Double
Get
Return Me.lat
End Get
End Property
Public ReadOnly Property Longitude As Double
Get
Return Me.lon
End Get
End Property
End Structure
A LocationReporter classe fornece a IObserver<T> implementação.The LocationReporter class provides the IObserver<T> implementation. Ele exibe informações sobre o local atual para o console.It displays information about the current location to the console. Seu construtor inclui um name parâmetro, que permite que a LocationReporter instância se identifique em sua saída de cadeia de caracteres.Its constructor includes a name parameter, which allows the LocationReporter instance to identify itself in its string output. Ele também inclui um Subscribe método, que encapsula uma chamada para o método do provedor Subscribe .It also includes a Subscribe method, which wraps a call to the provider's Subscribe method. Isso permite que o método atribua a IDisposable referência retornada a uma variável privada.This enables the method to assign the returned IDisposable reference to a private variable. A LocationReporter classe também inclui um Unsubscribe método, que chama o IDisposable.Dispose método do objeto retornado pelo IObservable<T>.Subscribe método.The LocationReporter class also includes an Unsubscribe method, which calls the IDisposable.Dispose method of the object returned by the IObservable<T>.Subscribe method. O código a seguir define a LocationReporter classe.The following code defines the LocationReporter class.
using System;
public class LocationReporter : IObserver<Location>
{
private IDisposable unsubscriber;
private string instName;
public LocationReporter(string name)
{
this.instName = name;
}
public string Name
{ get{ return this.instName; } }
public virtual void Subscribe(IObservable<Location> provider)
{
if (provider != null)
unsubscriber = provider.Subscribe(this);
}
public virtual void OnCompleted()
{
Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", this.Name);
this.Unsubscribe();
}
public virtual void OnError(Exception e)
{
Console.WriteLine("{0}: The location cannot be determined.", this.Name);
}
public virtual void OnNext(Location value)
{
Console.WriteLine("{2}: The current location is {0}, {1}", value.Latitude, value.Longitude, this.Name);
}
public virtual void Unsubscribe()
{
unsubscriber.Dispose();
}
}
Public Class LocationReporter : Implements IObserver(Of Location)
Dim unsubscriber As IDisposable
Dim instName As String
Public Sub New(ByVal name As String)
Me.instName = name
End Sub
Public ReadOnly Property Name As String
Get
Return instName
End Get
End Property
Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Location))
If provider Is Nothing Then Exit Sub
unsubscriber = provider.Subscribe(Me)
End Sub
Public Overridable Sub OnCompleted() Implements System.IObserver(Of Location).OnCompleted
Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", Me.Name)
Me.Unsubscribe()
End Sub
Public Overridable Sub OnError(ByVal e As System.Exception) Implements System.IObserver(Of Location).OnError
Console.WriteLine("{0}: The location cannot be determined.", Me.Name)
End Sub
Public Overridable Sub OnNext(ByVal value As Location) Implements System.IObserver(Of Location).OnNext
Console.WriteLine("{2}: The current location is {0}, {1}", value.Latitude, value.Longitude, Me.Name)
End Sub
Public Overridable Sub Unsubscribe()
unsubscriber.Dispose()
End Sub
End Class
A LocationTracker classe fornece a IObservable<T> implementação.The LocationTracker class provides the IObservable<T> implementation. Seu TrackLocation método é passado para um Location objeto anulável que contém os dados de latitude e longitude.Its TrackLocation method is passed a nullable Location object that contains the latitude and longitude data. Se o Location valor não for null , o TrackLocation método chamará o OnNext método de cada observador.If the Location value is not null, the TrackLocation method calls the OnNext method of each observer.
public class LocationTracker : IObservable<Location>
{
public LocationTracker()
{
observers = new List<IObserver<Location>>();
}
private List<IObserver<Location>> observers;
public IDisposable Subscribe(IObserver<Location> observer)
{
if (! observers.Contains(observer))
observers.Add(observer);
return new Unsubscriber(observers, observer);
}
private class Unsubscriber : IDisposable
{
private List<IObserver<Location>>_observers;
private IObserver<Location> _observer;
public Unsubscriber(List<IObserver<Location>> observers, IObserver<Location> observer)
{
this._observers = observers;
this._observer = observer;
}
public void Dispose()
{
if (_observer != null && _observers.Contains(_observer))
_observers.Remove(_observer);
}
}
public void TrackLocation(Nullable<Location> loc)
{
foreach (var observer in observers) {
if (! loc.HasValue)
observer.OnError(new LocationUnknownException());
else
observer.OnNext(loc.Value);
}
}
public void EndTransmission()
{
foreach (var observer in observers.ToArray())
if (observers.Contains(observer))
observer.OnCompleted();
observers.Clear();
}
}
Public Class LocationTracker : Implements IObservable(Of Location)
Public Sub New()
observers = New List(Of IObserver(Of Location))
End Sub
Private observers As List(Of IObserver(Of Location))
Public Function Subscribe(ByVal observer As System.IObserver(Of Location)) As System.IDisposable _
Implements System.IObservable(Of Location).Subscribe
If Not observers.Contains(observer) Then
observers.Add(observer)
End If
Return New Unsubscriber(observers, observer)
End Function
Private Class Unsubscriber : Implements IDisposable
Private _observers As List(Of IObserver(Of Location))
Private _observer As IObserver(Of Location)
Public Sub New(ByVal observers As List(Of IObserver(Of Location)), ByVal observer As IObserver(Of Location))
Me._observers = observers
Me._observer = observer
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
If _observer IsNot Nothing AndAlso _observers.Contains(_observer) Then
_observers.Remove(_observer)
End If
End Sub
End Class
Public Sub TrackLocation(ByVal loc As Nullable(Of Location))
For Each observer In observers
If Not loc.HasValue Then
observer.OnError(New LocationUnknownException())
Else
observer.OnNext(loc.Value)
End If
Next
End Sub
Public Sub EndTransmission()
For Each observer In observers.ToArray()
If observers.Contains(observer) Then observer.OnCompleted()
Next
observers.Clear()
End Sub
End Class
Se o Location valor for null , o TrackLocation método instanciará um LocationNotFoundException objeto, que é mostrado no exemplo a seguir.If the Location value is null, the TrackLocation method instantiates a LocationNotFoundException object, which is shown in the following example. Em seguida, ele chama cada método de observador OnError e passa para ele o LocationNotFoundException objeto.It then calls each observer's OnError method and passes it the LocationNotFoundException object. Observe que LocationNotFoundException deriva de Exception , mas não adiciona novos membros.Note that LocationNotFoundException derives from Exception but does not add any new members.
public class LocationUnknownException : Exception
{
internal LocationUnknownException()
{ }
}
Public Class LocationUnknownException : Inherits Exception
Friend Sub New()
End Sub
End Class
Os observadores se registram para receber notificações de um TrackLocation objeto chamando seu IObservable<T>.Subscribe método, que atribui uma referência ao objeto observador a um objeto genérico privado List<T> .Observers register to receive notifications from a TrackLocation object by calling its IObservable<T>.Subscribe method, which assigns a reference to the observer object to a private generic List<T> object. O método retorna um Unsubscriber objeto, que é uma IDisposable implementação que permite que os observadores parem de receber notificações.The method returns an Unsubscriber object, which is an IDisposable implementation that enables observers to stop receiving notifications. A LocationTracker classe também inclui um EndTransmission método.The LocationTracker class also includes an EndTransmission method. Quando nenhum dado de localização adicional está disponível, o método chama cada método de observador OnCompleted e, em seguida, limpa a lista interna de observadores.When no further location data is available, the method calls each observer's OnCompleted method and then clears the internal list of observers.
O código a seguir instancia o provedor e o observador.The following code then instantiates the provider and the observer.
using System;
class Program
{
static void Main(string[] args)
{
// Define a provider and two observers.
LocationTracker provider = new LocationTracker();
LocationReporter reporter1 = new LocationReporter("FixedGPS");
reporter1.Subscribe(provider);
LocationReporter reporter2 = new LocationReporter("MobileGPS");
reporter2.Subscribe(provider);
provider.TrackLocation(new Location(47.6456, -122.1312));
reporter1.Unsubscribe();
provider.TrackLocation(new Location(47.6677, -122.1199));
provider.TrackLocation(null);
provider.EndTransmission();
}
}
// The example displays output similar to the following:
// FixedGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6677, -122.1199
// MobileGPS: The location cannot be determined.
// The Location Tracker has completed transmitting data to MobileGPS.
Module Module1
Dim provider As LocationTracker
Sub Main()
' Define a provider and two observers.
provider = New LocationTracker()
Dim reporter1 As New LocationReporter("FixedGPS")
reporter1.Subscribe(provider)
Dim reporter2 As New LocationReporter("MobileGPS")
reporter2.Subscribe(provider)
provider.TrackLocation(New Location(47.6456, -122.1312))
reporter1.Unsubscribe()
provider.TrackLocation(New Location(47.6677, -122.1199))
provider.TrackLocation(Nothing)
provider.EndTransmission()
End Sub
End Module
' The example displays output similar to the following:
' FixedGPS: The current location is 47.6456, -122.1312
' MobileGPS: The current location is 47.6456, -122.1312
' MobileGPS: The current location is 47.6677, -122.1199
' MobileGPS: The location cannot be determined.
' The Location Tracker has completed transmitting data to MobileGPS.
Comentários
As IObserver<T> IObservable<T> interfaces e fornecem um mecanismo generalizado para notificação baseada em push, também conhecido como o padrão de design observador.The IObserver<T> and IObservable<T> interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. A IObservable<T> interface representa a classe que envia notificações (o provedor); a IObserver<T> interface representa a classe que as recebe (o observador).The IObservable<T> interface represents the class that sends notifications (the provider); the IObserver<T> interface represents the class that receives them (the observer). T representa a classe que fornece as informações de notificação.T represents the class that provides the notification information.
Uma IObserver<T> implementação se organiza para receber notificações de um provedor (uma IObservable<T> implementação), passando uma instância de si mesma para o método do provedor IObservable<T>.Subscribe .An IObserver<T> implementation arranges to receive notifications from a provider (an IObservable<T> implementation) by passing an instance of itself to the provider's IObservable<T>.Subscribe method. Esse método retorna um IDisposable objeto que pode ser usado para cancelar a assinatura do observador antes de o provedor concluir o envio de notificações.This method returns an IDisposable object that can be used to unsubscribe the observer before the provider finishes sending notifications.
A IObserver<T> interface define os três métodos a seguir que o observador deve implementar:The IObserver<T> interface defines the following three methods that the observer must implement:
O OnNext método, que normalmente é chamado pelo provedor para fornecer o observador com novas informações de dados ou estado.The OnNext method, which is typically called by the provider to supply the observer with new data or state information.
O OnError método, que é normalmente chamado pelo provedor para indicar que os dados estão indisponíveis, inacessíveis ou corrompidos, ou que o provedor experimentou alguma outra condição de erro.The OnError method, which is typically called by the provider to indicate that data is unavailable, inaccessible, or corrupted, or that the provider has experienced some other error condition.
O OnCompleted método, que normalmente é chamado pelo provedor para indicar que terminou de enviar notificações aos observadores.The OnCompleted method, which is typically called by the provider to indicate that it has finished sending notifications to observers.
Métodos
| OnCompleted() |
Notifica o observador que o provedor finalizou o envio das notificações baseadas em push.Notifies the observer that the provider has finished sending push-based notifications. |
| OnError(Exception) |
Notifica o observador de que o provedor sofreu uma condição de erro.Notifies the observer that the provider has experienced an error condition. |
| OnNext(T) |
Fornece novos dados ao observador.Provides the observer with new data. |