Procedura: Implementare un elemento ObserverHow to: Implement an Observer

Lo schema progettuale degli observer richiede una divisione tra un observer, che si registra per le notifiche, e un provider, che monitora i dati e invia notifiche a uno o più observer.The observer design pattern requires a division between an observer, which registers for notifications, and a provider, which monitors data and sends notifications to one or more observers. Questo argomento descrive come creare un observer.This topic discusses how to create an observer. Un argomento correlato, Procedura: Implementare un provider, descrive come creare un provider.A related topic, How to: Implement a Provider, discusses how to create an provider.

Per creare un observerTo create an observer

  1. Definire l'observer, che è un tipo che implementa l'interfaccia System.IObserver<T>.Define the observer, which is a type that implements the System.IObserver<T> interface. Ad esempio, il codice seguente definisce un tipo denominato TemperatureReporter che rappresenta un'implementazione costruita System.IObserver<T> con un argomento di tipo generico Temperature.For example, the following code defines a type named TemperatureReporter that is a constructed System.IObserver<T> implementation with a generic type argument of Temperature.

    public class TemperatureReporter : IObserver<Temperature>
    
    Public Class TemperatureReporter : Implements IObserver(Of Temperature)
    
  2. Se l'observer può smettere di ricevere notifiche prima che il provider chiami la relativa implementazione IObserver<T>.OnCompleted, definire una variabile privata che conterrà l'implementazione IDisposable restituita dal metodo IObservable<T>.Subscribe del provider.If the observer can stop receiving notifications before the provider calls its IObserver<T>.OnCompleted implementation, define a private variable that will hold the IDisposable implementation returned by the provider's IObservable<T>.Subscribe method. È anche necessario definire un metodo di sottoscrizione che chiama il metodo Subscribe del provider e archivia l'oggetto IDisposable restituito.You should also define a subscription method that calls the provider's Subscribe method and stores the returned IDisposable object. Ad esempio, il codice seguente definisce una variabile privata denominata unsubscriber e un metodo Subscribe che chiama il metodo Subscribe del provider e assegna l'oggetto restituito alla variabile unsubscriber.For example, the following code defines a private variable named unsubscriber and defines a Subscribe method that calls the provider's Subscribe method and assigns the returned object to the unsubscriber variable.

    public class TemperatureReporter : IObserver<Temperature>
    {
       private IDisposable unsubscriber;
       private bool first = true;
       private Temperature last;
    
       public virtual void Subscribe(IObservable<Temperature> provider)
       {
          unsubscriber = provider.Subscribe(this);
       }
    
    Public Class TemperatureReporter : Implements IObserver(Of Temperature)
    
       Private unsubscriber As IDisposable
       Private first As Boolean = True
       Private last As Temperature
    
       Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature))
          unsubscriber = provider.Subscribe(Me)
       End Sub
    
  3. Definire un metodo che consente all'observer di smettere di ricevere interrompere notifiche prima che il provider chiami la relativa implementazione IObserver<T>.OnCompleted, se questa funzionalità è necessaria.Define a method that enables the observer to stop receiving notifications before the provider calls its IObserver<T>.OnCompleted implementation, if this feature is required. L'esempio seguente definisce un metodo Unsubscribe.The following example defines an Unsubscribe method.

    public virtual void Unsubscribe()
    {
       unsubscriber.Dispose();
    }
    
    Public Overridable Sub Unsubscribe()
       unsubscriber.Dispose()
    End Sub
    
  4. Fornire le implementazioni dei tre metodi definiti dall'interfaccia IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError e IObserver<T>.OnCompleted.Provide implementations of the three methods defined by the IObserver<T> interface: IObserver<T>.OnNext, IObserver<T>.OnError, and IObserver<T>.OnCompleted. A seconda del provider e delle esigenze dell'applicazione, i metodi OnError e OnCompleted possono essere implementazioni dello stub.Depending on the provider and the needs of the application, the OnError and OnCompleted methods can be stub implementations. Si noti che il metodo OnError non deve gestire l'oggetto Exception passato come eccezione e che il metodo OnCompleted è libero di chiamare l'implementazione IDisposable.Dispose del provider.Note that the OnError method should not handle the passed Exception object as an exception, and the OnCompleted method is free to call the provider's IDisposable.Dispose implementation. L'esempio seguente mostra l'implementazione IObserver<T> della classe TemperatureReporter.The following example shows the IObserver<T> implementation of the TemperatureReporter class.

    public virtual void OnCompleted() 
    {
       Console.WriteLine("Additional temperature data will not be transmitted.");
    }
    
    public virtual void OnError(Exception error)
    {
       // Do nothing.
    }
    
    public virtual void OnNext(Temperature value)
    {
       Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date);
       if (first)
       {
          last = value;
          first = false;
       }
       else
       {
          Console.WriteLine("   Change: {0}° in {1:g}", value.Degrees - last.Degrees,
                                                        value.Date.ToUniversalTime() - last.Date.ToUniversalTime());
       }
    }
    
    Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted
       Console.WriteLine("Additional temperature data will not be transmitted.")
    End Sub
    
    Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError
       ' Do nothing.
    End Sub
    
    Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext
       Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date)
       If first Then
          last = value
          first = False
       Else
          Console.WriteLine("   Change: {0}° in {1:g}", value.Degrees - last.Degrees,
                                                        value.Date.ToUniversalTime - last.Date.ToUniversalTime)
       End If
    End Sub
    

EsempioExample

L'esempio seguente contiene il codice sorgente completo per la classe TemperatureReporter, che fornisce l'implementazione IObserver<T> per un'applicazione di monitoraggio della temperatura.The following example contains the complete source code for the TemperatureReporter class, which provides the IObserver<T> implementation for a temperature monitoring application.

public class TemperatureReporter : IObserver<Temperature>
{
   private IDisposable unsubscriber;
   private bool first = true;
   private Temperature last;

   public virtual void Subscribe(IObservable<Temperature> provider)
   {
      unsubscriber = provider.Subscribe(this);
   }

   public virtual void Unsubscribe()
   {
      unsubscriber.Dispose();
   }

   public virtual void OnCompleted() 
   {
      Console.WriteLine("Additional temperature data will not be transmitted.");
   }

   public virtual void OnError(Exception error)
   {
      // Do nothing.
   }

   public virtual void OnNext(Temperature value)
   {
      Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date);
      if (first)
      {
         last = value;
         first = false;
      }
      else
      {
         Console.WriteLine("   Change: {0}° in {1:g}", value.Degrees - last.Degrees,
                                                       value.Date.ToUniversalTime() - last.Date.ToUniversalTime());
      }
   }
}
Public Class TemperatureReporter : Implements IObserver(Of Temperature)

   Private unsubscriber As IDisposable
   Private first As Boolean = True
   Private last As Temperature

   Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature))
      unsubscriber = provider.Subscribe(Me)
   End Sub

   Public Overridable Sub Unsubscribe()
      unsubscriber.Dispose()
   End Sub

   Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted
      Console.WriteLine("Additional temperature data will not be transmitted.")
   End Sub

   Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError
      ' Do nothing.
   End Sub

   Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext
      Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date)
      If first Then
         last = value
         first = False
      Else
         Console.WriteLine("   Change: {0}° in {1:g}", value.Degrees - last.Degrees,
                                                       value.Date.ToUniversalTime - last.Date.ToUniversalTime)
      End If
   End Sub
End Class

Vedere ancheSee Also

IObserver<T>
Modello di progettazione observerObserver Design Pattern
Procedura: Implementare un providerHow to: Implement a Provider
Procedure consigliate per un modello di progettazione observerObserver Design Pattern Best Practices