is there a way to define the signature of a delegate in an interface without defining the signature twice?
-
Hi, I have the following code:
class Program
{
static void Main(string[] args)
{
ProductCounterWatcher w = new ProductCounterWatcher();
ICounterProcessor p = new PrdStandStillDetector();
w.OnCounterChanged += p.CounterChanged;
w.Detect();
w.OnCounterChanged -= p.CounterChanged;
}
}
//-----------------------------------------------------------------------------------
public class ProductCounter
{
public int Value { get; set; }
public DateTime Timestamp { get; set; }public override string ToString() { return string.Format("\[ProductCounter:{0},{1}\]", Timestamp, Value); }
}
//-----------------------------------------------------------------------------------
public interface ICounterProcessor
{
void CounterChanged(object source, CounterChangedEventArgs e); // <<<----
}
//-----------------------------------------------------------------------------------public delegate void CounterChangedHandler(object source, CounterChangedEventArgs e); // <<<----
//-----------------------------------------------------------------------------------public class CounterChangedEventArgs : EventArgs
{
public ProductCounter Counter { get; set; }public CounterChangedEventArgs(ProductCounter counter) { this.Counter = counter; }
}
//-----------------------------------------------------------------------------------
public class PrdStandStillDetector : ICounterProcessor
{
public void CounterChanged(object source, CounterChangedEventArgs e)
{
}
}
//-----------------------------------------------------------------------------------
public class ProductCounterWatcher
{
public CounterChangedHandler OnCounterChanged;public void Detect() { if (OnCounterChanged != null) OnCounterChanged(this, new CounterChangedEventArgs(new ProductCounter() { Timestamp = DateTime.Now, Value = 1 })); }
}
I have to define the procedure signature twice (see <<<--- mark). is there a way to avoid this and thus only define the signature once? Thanks.
-
Hi, I have the following code:
class Program
{
static void Main(string[] args)
{
ProductCounterWatcher w = new ProductCounterWatcher();
ICounterProcessor p = new PrdStandStillDetector();
w.OnCounterChanged += p.CounterChanged;
w.Detect();
w.OnCounterChanged -= p.CounterChanged;
}
}
//-----------------------------------------------------------------------------------
public class ProductCounter
{
public int Value { get; set; }
public DateTime Timestamp { get; set; }public override string ToString() { return string.Format("\[ProductCounter:{0},{1}\]", Timestamp, Value); }
}
//-----------------------------------------------------------------------------------
public interface ICounterProcessor
{
void CounterChanged(object source, CounterChangedEventArgs e); // <<<----
}
//-----------------------------------------------------------------------------------public delegate void CounterChangedHandler(object source, CounterChangedEventArgs e); // <<<----
//-----------------------------------------------------------------------------------public class CounterChangedEventArgs : EventArgs
{
public ProductCounter Counter { get; set; }public CounterChangedEventArgs(ProductCounter counter) { this.Counter = counter; }
}
//-----------------------------------------------------------------------------------
public class PrdStandStillDetector : ICounterProcessor
{
public void CounterChanged(object source, CounterChangedEventArgs e)
{
}
}
//-----------------------------------------------------------------------------------
public class ProductCounterWatcher
{
public CounterChangedHandler OnCounterChanged;public void Detect() { if (OnCounterChanged != null) OnCounterChanged(this, new CounterChangedEventArgs(new ProductCounter() { Timestamp = DateTime.Now, Value = 1 })); }
}
I have to define the procedure signature twice (see <<<--- mark). is there a way to avoid this and thus only define the signature once? Thanks.
So you're not really defining it twice; you're defining it once and then defining a delegate with a matching signature in the interface, Here's what I think you're looking for:
public delegate void CounterChangedHandler(object source, CounterChangedEventArgs e);
public interface ICounterProcessor
{
CounterChangedHandler CounterChanged { get; }
}When you have pre-defined delegates like this, you can use them in the same way that you would Action or Func.
"There are three kinds of lies: lies, damned lies and statistics." - Benjamin Disraeli
-
So you're not really defining it twice; you're defining it once and then defining a delegate with a matching signature in the interface, Here's what I think you're looking for:
public delegate void CounterChangedHandler(object source, CounterChangedEventArgs e);
public interface ICounterProcessor
{
CounterChangedHandler CounterChanged { get; }
}When you have pre-defined delegates like this, you can use them in the same way that you would Action or Func.
"There are three kinds of lies: lies, damned lies and statistics." - Benjamin Disraeli
Thank you for the reply. It is not what I mean; In your solution the ICounterprocessor can raise the event, but it's meant to react on the event, like an observer. Maibe I better forget the whole event stuff, and change to Observer like structure?
-
Thank you for the reply. It is not what I mean; In your solution the ICounterprocessor can raise the event, but it's meant to react on the event, like an observer. Maibe I better forget the whole event stuff, and change to Observer like structure?
No sir, I'm afraid that's not correct. That would be:
public interface ICounterProcessor
{
event CounterChangedHandler CounterChanged;
}But I didn't format it as an accessor, so I'll take bads on that (I've been playing using abstracts too much lately rather than interfaces). So I modified the code snippet in the last to make it a property accessor. It will work, and is much less complicated than an Observer pattern. Try it :)
"There are three kinds of lies: lies, damned lies and statistics." - Benjamin Disraeli
-
Hi, I have the following code:
class Program
{
static void Main(string[] args)
{
ProductCounterWatcher w = new ProductCounterWatcher();
ICounterProcessor p = new PrdStandStillDetector();
w.OnCounterChanged += p.CounterChanged;
w.Detect();
w.OnCounterChanged -= p.CounterChanged;
}
}
//-----------------------------------------------------------------------------------
public class ProductCounter
{
public int Value { get; set; }
public DateTime Timestamp { get; set; }public override string ToString() { return string.Format("\[ProductCounter:{0},{1}\]", Timestamp, Value); }
}
//-----------------------------------------------------------------------------------
public interface ICounterProcessor
{
void CounterChanged(object source, CounterChangedEventArgs e); // <<<----
}
//-----------------------------------------------------------------------------------public delegate void CounterChangedHandler(object source, CounterChangedEventArgs e); // <<<----
//-----------------------------------------------------------------------------------public class CounterChangedEventArgs : EventArgs
{
public ProductCounter Counter { get; set; }public CounterChangedEventArgs(ProductCounter counter) { this.Counter = counter; }
}
//-----------------------------------------------------------------------------------
public class PrdStandStillDetector : ICounterProcessor
{
public void CounterChanged(object source, CounterChangedEventArgs e)
{
}
}
//-----------------------------------------------------------------------------------
public class ProductCounterWatcher
{
public CounterChangedHandler OnCounterChanged;public void Detect() { if (OnCounterChanged != null) OnCounterChanged(this, new CounterChangedEventArgs(new ProductCounter() { Timestamp = DateTime.Now, Value = 1 })); }
}
I have to define the procedure signature twice (see <<<--- mark). is there a way to avoid this and thus only define the signature once? Thanks.
How about using the built-in EventHandler<TEventArgs>[^] delegate? You should also mark the event with the
event
keyword, and drop the "On" prefix to follow the .NET naming standards.public class ProductCounterWatcher
{
public event EventHandler<CounterChangedEventArgs> CounterChanged;public void Detect() { EventHandler<CounterChangedEventArgs> handler = CounterChanged; if (handler != null) handler(this, new CounterChangedEventArgs(new ProductCounter() { Timestamp = DateTime.Now, Value = 1 })); }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
How about using the built-in EventHandler<TEventArgs>[^] delegate? You should also mark the event with the
event
keyword, and drop the "On" prefix to follow the .NET naming standards.public class ProductCounterWatcher
{
public event EventHandler<CounterChangedEventArgs> CounterChanged;public void Detect() { EventHandler<CounterChangedEventArgs> handler = CounterChanged; if (handler != null) handler(this, new CounterChangedEventArgs(new ProductCounter() { Timestamp = DateTime.Now, Value = 1 })); }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Oke, that makes sense. Thank you.