views:

79

answers:

8

There are many questions about events in interfaces. Here are a couple:

As interfaces are used to enforce a contract for implementation, this makes no sense to me, because it doesn't enforce the actual raising of the event. The specific implementation can always have the event, but not raise it anywhere. Consider the following:

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

public class SomeClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string SomeProperty
    {
        get { return this.someField; }
        set { this.someField = value; }
    }

    private string someField;
}

The thing above will compile and work, but even if I subscribe to the PropertyChanged event, nothing will happen. What would be a way to enforce that an event is actually raised, and if not, why have events in interfaces in the first place?

+4  A: 

The interface contract defines that the event must be implemented, and may be subscribed to. Actually raising it is left up to the concrete implementation. There is no way to enforce that an event is raised. What if the circumstances required to trigger the event never occur?

Mitch Wheat
I think what the OP is meaning is that e.g. in his example it feels like part of the contract that the PropertyChanged event fires whenever SomeProperty changes. That unfortunately can't be enforced at an interface level. A concrete class can implement the interface and disregard the event, and that doesn't seem very nice.
Iain Galloway
'The interface contract defines that the event must be implemented' - not exactly, although common sense dictates this. To be precise, the interface declaration syntactically enforces the implementing class to have an event with a matching signature but it says nothing about if and how it should work. It could e.g. throw an exception or do nothing - and the compiler would be fully satisfied...
Thomas Weller
+1  A: 

Another situation in which PropertyChanged will never be raised is the circumstance that the property is never changed! Do you want to be warned about that too?

But seriously, interfaces are for enforcing a contract of supported behaviour - if you want to enforce actual behaviour (ie - IF this happens THEN that happens), use (automated) testing.

AakashM
+1  A: 

Integration tests or unit tests are the only way that I see you could do what you want. You are then making sure in your implementation the behaviour is what you expect.

Paul Hadfield
+4  A: 

You misunderstood the concept of an interface: It explicitely declares an object's behaviour, but it does not enforce it in any way. The programmer is still fully responsible for implementing the interface behaviour correctly. This is nothing a compiler could do.

It's the same as with other contracts, when the involved parties just refuse to adhere to its content...

Thomas

Thomas Weller
+1 but note that a compiler (or some pre/post-processor) *can* do it if the contract is formally specified: theorem proving engines have been build. Examples: ESC/Java, .NET code contracts. It might not be very practical yet, but it exists.
Wim Coenen
@Wim - Yep, I know, you might do something like this in .NET with MS Code Contracts or e.g. PostSharp. It's just that it seems to me that declaring an interface is technically another story: I simply declare (describe) a software component's behaviour and that's it...
Thomas Weller
+1  A: 

Nothing's really enforced in an interface, you can just put empty method stubs in after all (as long as you return something of the correct type).

The best way to ensure things like this are behaving correctly is to have plenty of tests.

One thing you might consider is code contracts, which let you specify conditions which have to be true at certain times, and these are actually enforced. However, AFAIK this doesn't work with events.

Grant Crofton
"as long as you return something of the correct type" - or throw an exception.
Greg
I got the point, thanks. My confusion probably comes from the fact that when you implement an interface method, the method HAS TO BE there, you just put in the code. While with an event, you need to introduce another method which actually raises it. The interface does not mandate the existence of that other method. But that's just a pattern after all, you can still raise the event even without this second method, so conceptually all is fine I guess.
Slavo
+3  A: 

The same can be said for methods: the interface doesn't enforce that they do anything useful, they could all just return null/0/void. Similarly, the implementation is free to raise/not raise an eevent whenever it wants.

If you want to ensure that certain behaviors are executed, then implement them as a abstract base class. Make the public methods public and non-virtual, and then have them call virtual protected methods and raise events. This is the template-method pattern, and it lets you have more control over sub-class behavior.

Chris
A: 

My take is that this provides a means of subscribing to an event when all you have reference to is the interface an object is using. Otherwise you would not be able to subscribe to the event at all. You are correct that it does not guarantee that the event is used.

INotifyPropertyChanged x = new SomeClass();
x.PropertyChanged += MyHandler;  //you get the idea

If the event were not defined on INotifyPropertyChanged you would not be able to add your handler.

David
A: 

why u want to enforce raising events? may be u have an event and never use it except in some situation:

if(exceptionAccured) { logger.LogExceptionsEvent += ....; }

SaeedAlg