4

Quote from: http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx

"Invoking an event can only be done from within the class that declared the event."

I am puzzled why there is such restriction. Without this limitation I would be able to write a class (one class) which once for good manages sending the events for a given category -- like INotifyPropertyChanged.

With this limitation I have to copy and paste the same (the same!) code all over again. I know that designers of C# don't value code reuse too much (*), but gee... copy&paste. How productive is that?

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

In every class changing something, to the end of your life. Scary!

So, while I am reverting my extra sending class (I am too gullible) to old, "good" copy&paste way, can you see

what terrible could happen with the ability to send events for a sender?

If you know any tricks how to avoid this limitation -- don't hesitate to answer as well!

(*) with multi inheritance I could write universal sender once for good in even clearer manner, but C# does not have multi inheritance

Edits

The best workaround so far

Introducing interface

public interface INotifierPropertyChanged : INotifyPropertyChanged
{
    void OnPropertyChanged(string property_name);
}

adding new extension method Raise for PropertyChangedEventHandler. Then adding mediator class for this new interface instead of basic INotifyPropertyChanged.

So far it is minimal code that let's send you message from nested object in behalf of its owner (when owner required such logic).

THANK YOU ALL FOR THE HELP AND IDEAS.

Edit 1

Guffa wrote:

"You couldn't cause something to happen by triggering an event from the outside,"

It is interesting point, because... I can. It is exactly why I am asking. Take a look.

Let's say you have class string. Not interesting, right? But let's pack it with Invoker class, which send events every time it changed.

Now:

class MyClass : INotifyPropertyChanged
{
    public SuperString text { get; set; }
}

Now, when text is changed MyClass is changed. So when I am inside text I know, that if only I have owner, it is changed as well. So I could send event on its behalf. And it would be semantically 100% correct.

Remark: my class is just a bit smarter -- owner sets if it would like to have such logic.

Edit 2

Idea with passing the event handler -- "2" won't be displayed.

public class Mediator
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property_name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property_name));
    }

    public void Link(PropertyChangedEventHandler send_through)
    {
        PropertyChanged += new PropertyChangedEventHandler((obj, args) => {
            if (send_through != null)
                send_through(obj, args);
        });
    }

    public void Trigger()
    {
        OnPropertyChanged("hello world");
    }
}
public class Sender
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Sender(Mediator mediator)
    {
        PropertyChanged += Listener1;
        mediator.Link(PropertyChanged);
        PropertyChanged += Listener2;

    }
    public void Listener1(object obj, PropertyChangedEventArgs args)
    {
        Console.WriteLine("1");
    }
    public void Listener2(object obj, PropertyChangedEventArgs args)
    {
        Console.WriteLine("2");
    }
}

    static void Main(string[] args)
    {
        var mediator = new Mediator();
        var sender = new Sender(mediator);
        mediator.Trigger();

        Console.WriteLine("EOT");
        Console.ReadLine();
    }

Edit 3

As an comment to all argument about misuse of direct event invoking -- misuse is of course still possible. All it takes is implementing the described above workaround.

Edit 4

Small sample of my code (end use), Dan please take a look:

public class ExperimentManager : INotifierPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string property_name)
    {
        PropertyChanged.Raise(this, property_name);
    }


    public enum Properties
    {
        NetworkFileName,
        ...
    }

    public NotifierChangedManager<string> NetworkFileNameNotifier;
    ...

    public string NetworkFileName 
    { 
         get { return NetworkFileNameNotifier.Value; } 
         set { NetworkFileNameNotifier.Value = value; } 
    }

    public ExperimentManager()
    {
        NetworkFileNameNotifier = 
            NotifierChangedManager<string>.CreateAs(this, Properties.NetworkFileName.ToString());
        ... 
    }
Community
  • 1
  • 1
greenoldman
  • 16,895
  • 26
  • 119
  • 185
  • Have been wondering the same many times :) Waiting for a nice answer to this. – Marcus Sep 04 '10 at 15:17
  • (*) It's not C# that doesn't support multiple inheritance, it's the .NET framework. – Guffa Sep 04 '10 at 15:38
  • There is a thing as *too* much abstraction, and delegating the work of those 2 (or in your case 4) lines of code to an external helper class seems like a great example of that. – Kirk Woll Sep 04 '10 at 15:40
  • 1
    Also, you could create an extension method called "Raise" on PropertyChangedEventHandler so that your implementation would be PropertyChanged.Raise(this, name); Seems pretty concise to me. – Kirk Woll Sep 04 '10 at 15:46
  • @Kirk, Abstractions -- 4 lines like milion times, means a lot of time and several chances to make a "stupid" mistake. I like my programs to be 100% perfect, not 98%. Extension method -- no, you can't do this for exactly the reason described in the question. – greenoldman Sep 04 '10 at 15:57
  • @Macias: see this answer to a related question - http://stackoverflow.com/questions/780022/raise-base-class-events-in-derived-classes-c/780115#780115 – Matt Ellen Sep 04 '10 at 16:27
  • @macias: You sound like you come from a C++ background, am I right? You are looking for features that allow you to shoot yourself in the foot, and you justify that by saying that you won’t. How happy would you be to maintain someone else’s code that does? – Timwi Sep 04 '10 at 17:10
  • @Timwi, please don't go in personal quarrel, ok? Be specific, technical and on the topic. Thank you. – greenoldman Sep 04 '10 at 18:08
  • @macias: Sorry, it wasn’t meant to be personal. It is the essence of why C# doesn’t let you fire foreign events (and also why it doesn’t have multiple inheritance etc.). – Timwi Sep 04 '10 at 18:15
  • 1
    @macias: I think you've misunderstood Kirk Woll's suggestion. Writing an extension method on a `PropertyChangedEventHandler` that does just what he describes is completely possible. Then you would *use* this extension method from the class where the event is declared, without having to write your `OnPropertyChanged` code. It doesn't save you *all* the typing; but it does save you some. – Dan Tao Sep 04 '10 at 18:33
  • @Dan, I am sorry, I misread the comment. Anyway, it saves 1 line, you still have to copy the handler -- i.e. call to this method. – greenoldman Sep 04 '10 at 18:57
  • @macias: 1 line? Oh come on, it saves like 6. (Granted, most of those are just curly braces, but still.) – Dan Tao Sep 04 '10 at 18:59
  • You are right, I will use it for sure, but I am still looking for something with bigger compression ratio :-) – greenoldman Sep 04 '10 at 19:03

6 Answers6

5

Think about it for a second before going off on a rant. If any method could invoke an event on any object, would that not break encapsulation and also be confusing? The point of events is so that instances of the class with the event can notify other objects that some event has occurred. The event has to come from that class and not from any other. Otherwise, events become meaningless because anyone can trigger any event on any object at any time meaning that when an event fires, you don't know for sure if it's really because the action it represents took place, or just because some 3rd party class decided to have some fun.

That said, if you want to be able to allow some sort of mediator class send events for you, just open up the event declaration with the add and remove handlers. Then you could do something like this:

public event PropertyChangedEventHandler PropertyChanged {
    add {
        propertyChangedHelper.PropertyChanged += value;
    }
    remove {
        propertyChangedHelper.PropertyChanged -= value;
    }
}

And then the propertyChangedHelper variable can be an object of some sort that'll actually fire the event for the outer class. Yes, you still have to write the add and remove handlers, but it's fairly minimal and then you can use a shared implementation of whatever complexity you want.

siride
  • 200,666
  • 4
  • 41
  • 62
  • It would be confusing if you use it all the time--but the point is that nobody forces you to use it (quite contrary to current state). It is similar to operator overloading in Java--it is (or was?) forbidden because somebody somewhere could overload it in a bad manner. And for that reason **all** developers are not allowed to do it. I didn't quite get the mediator pattern here -- I have a class which inherits from INotifyPropertyChanged already (and it has to be that way), the mediator (I wrote it before I post the question) is inable to invoke the event for this class, because it is external. – greenoldman Sep 04 '10 at 15:45
  • I don't think it's equivalent to that. There's never a good reason for a class to invoke an other object's events. That's from the meaning of an event. In other words, I don't think it's possible for that ever to be done correctly, at least from a semantics point of view. With operator overloading, at least, it actually makes sense in many cases. – siride Sep 04 '10 at 16:25
  • I was being sloppy with my terminology. It's not necessarily a mediator. The point is that you have some class that implements property change notification business. This is as an alternative to multiple inheritance (using composition instead). – siride Sep 04 '10 at 16:26
  • Yes, that is my case -- so it is correct (in sense of workflow logic), yet I cannot model it. – greenoldman Sep 04 '10 at 16:34
  • It's not correct. Sending an event from another class is never correct. If your workflow logic requires that, then you need to rethink your workflow or your implementation or both. – siride Sep 04 '10 at 17:31
  • Did you read my "edit"? It is 100% percent correct because I asked nested object "please, send the event in behalf of me". IOW: when you consider multi-part object, the state of the object is changed when any part is changed (consider tree structure). If a node knows the owner (tree) it is correct to send event from node "hey, the tree is changed". – greenoldman Sep 04 '10 at 18:15
  • I know you think that sounds reasonable, but the semantics are still wrong. The nodes are changing, so they can send events about that, and the tree can listen for those events and then in turn send its own event saying that it changed. But neither should send events on behalf of the other. I'm sorry, but you'll have to accept that that is never correct and that's why MS made it hard to do. – siride Sep 05 '10 at 14:29
4

Allowing anyone to raise any event puts us in this problem:

@Rex M: hey everybody, @macias just raised his hand!

@macias: no, I didn't.

@everyone: too late! @Rex M said you did, and we all took action believing it.

This model is to protect you from writing applications that can easily have invalid state, which is one of the most common sources of bugs.

Rex M
  • 142,167
  • 33
  • 283
  • 313
  • Even if you will send event that something was changed, does not mean the state is invalid. And I try to weight here the cost of external invoking even vs. internal. Allowing anyone to raise any event does not mean you will write this in all your classes, right? But forcing programmer to copy&paste code means you have to copy&paste it in all your classes. – greenoldman Sep 04 '10 at 15:40
  • @macias it doesn't mean the state is invalid, it is just opens the door to making it much more *easy* for you to write code where the state is invalid, with very little benefit in exchange. – Rex M Sep 04 '10 at 16:52
  • The benefit for me is obvious -- it is saving my time big time. Time to copy & paste, time to analyze the the same code all over again. Reuse concept was not invented for no purpose -- it's a big saving for me. – greenoldman Sep 04 '10 at 18:08
  • 1
    @macias it sounds like - as you said at the end of your question - multiple inheritance might be a good solution for this problem. Allowing outside callers to raise events, however, is not. – Rex M Sep 04 '10 at 20:00
  • Yes, it would be much better -- because in such case the sender would send its own messages. – greenoldman Sep 05 '10 at 10:47
2

I think you're misunderstanding the restriction. What this is trying to say is that only the class which declared the event should actually cause it to be raised. This is different than writing a static helper class to encapsulate the actual event handler implementation.

A class A that is external to the class which declares the event B should not be able to cause B to raise that event directly. The only way A should have to cause B to raise the event is to perform some action on B which, as a result of performing that action raises the event.

In the case of INotifyPropertyChanged, given the following class:

public class Test : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private string name;

   public string Name
   {
      get { return this.name; }
      set { this.name = value; OnNotifyPropertyChanged("Name"); }
   }

   protected virtual void OnPropertyChanged(string name)
   {
       PropertyChangedEventHandler  temp = PropertyChanged;
       if (temp!= null)
       {
          temp(this, new PropertyChangedEventArgs(name));
       }
   }
}

The only way for a class consuming Test to cause Test to raise the PropertyChanged event is by setting the Name property:

public void TestMethod()
{
    Test t = new Test();
    t.Name = "Hello"; // This causes Test to raise the PropertyChanged event
}

You would not want code that looked like:

public void TestMethod()
{
    Test t = new Test();
    t.Name = "Hello";
    t.OnPropertyChanged("Name");
}

All of that being said, it is perfectly acceptable to write a helper class which encapsualtes the actual event handler implementation. For example, given the following EventManager class:

/// <summary>
/// Provides static methods for event handling. 
/// </summary>
public static class EventManager
{
    /// <summary>
    /// Raises the event specified by <paramref name="handler"/>.
    /// </summary>
    /// <typeparam name="TEventArgs">
    /// The type of the <see cref="EventArgs"/>
    /// </typeparam>
    /// <param name="sender">
    /// The source of the event.
    /// </param>
    /// <param name="handler">
    /// The <see cref="EventHandler{TEventArgs}"/> which 
    /// should be called.
    /// </param>
    /// <param name="e">
    /// An <see cref="EventArgs"/> that contains the event data.
    /// </param>
    public static void OnEvent<TEventArgs>(object sender, EventHandler<TEventArgs> handler, TEventArgs e)
         where TEventArgs : EventArgs
    {
        // Make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        EventHandler<TEventArgs> tempHandler = handler;

        // Event will be null if there are no subscribers
        if (tempHandler != null)
        {
            tempHandler(sender, e);
        }
    }

    /// <summary>
    /// Raises the event specified by <paramref name="handler"/>.
    /// </summary>
    /// <param name="sender">
    /// The source of the event.
    /// </param>
    /// <param name="handler">
    /// The <see cref="EventHandler"/> which should be called.
    /// </param>
    public static void OnEvent(object sender, EventHandler handler)
    {
        OnEvent(sender, handler, EventArgs.Empty);
    }

    /// <summary>
    /// Raises the event specified by <paramref name="handler"/>.
    /// </summary>
    /// <param name="sender">
    /// The source of the event.
    /// </param>
    /// <param name="handler">
    /// The <see cref="EventHandler"/> which should be called.
    /// </param>
    /// <param name="e">
    /// An <see cref="EventArgs"/> that contains the event data.
    /// </param>
    public static void OnEvent(object sender, EventHandler handler, EventArgs e)
    {
        // Make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        EventHandler tempHandler = handler;

        // Event will be null if there are no subscribers
        if (tempHandler != null)
        {
            tempHandler(sender, e);
        }
    }
}

It's perfectly legal to change Test as follows:

public class Test : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private string name;

   public string Name
   {
      get { return this.name; }
      set { this.name = value; OnNotifyPropertyChanged("Name"); }
   }

   protected virtual void OnPropertyChanged(string name)
   {
       EventHamanger.OnEvent(this, PropertyChanged, new PropertyChangedEventArgs(name));
   }
}
Scott Dorman
  • 42,236
  • 12
  • 79
  • 110
  • Your use of those `tempHandler` local variables in the `OnEvent` overloads is redundant, you know. There's no such thing as a race condition that reassigns the variables copied locally to the stack! – Dan Tao Sep 04 '10 at 18:42
  • Thank you for the code. However you have still this method OnPropertyChanged in your Rest class. Look at the line: "this.name = value". Do the name changed? YES. So at this point you know the Test changed. The idea is to send event from "name" through "Test" to its listeners. – greenoldman Sep 04 '10 at 19:07
  • @macias: Behavior like what you just described is actually not only *disallowed*, it is **completely impossible** since the `name` *variable* is not the same as the *object* to which `name` points. That is to say, the object knows nothing about the variable (how could it?) -- see my update. (There's still something *like* what you're asking that could *theoretically* be possible, though it is currently not legal. That is what I'm talking about in my answer.) – Dan Tao Sep 04 '10 at 19:33
  • @Dan, well, it depends what class you use for name. In my case it is string with notifier manager built in. – greenoldman Sep 04 '10 at 19:38
  • @Dan Tao: it's not redundant at all, actually. The point is that if he didn't use a local variable, and just tested the field before invoking it, there would be a race condition (between testing the field and then invoking it). By copying the field to a local variable, it will no longer matter whether the field changes because you can just use the local copy, which you rightly point out, cannot be changed. – siride Sep 05 '10 at 14:32
  • @siride: It **is** redundant. `handler` is **already a local variable** because it has been passed as a parameter to a method of this `EventManager` class. The original sender's private delegate field could be changed to `null` and it would not affect the `handler` variable already living in the scope of an `EventManager.OnPropertyChanged` call (for instance); so there's no race condition to prevent. – Dan Tao Sep 06 '10 at 09:17
  • @Dan Tao: d'oh! I missed that parameter since I need to scroll over to see it. – siride Sep 06 '10 at 15:06
1

First of all I must say, events are actually meant to be invoked from within the object only when any external eventhandler is attached to it.

So basically, the event gives you a callback from an object and gives you a chance to set the handler to it so that when the event occurs it automatically calls the method.

This is similar of sending a value of variable to a member. You can also define a delegate and send the handler the same way. So basically its the delegate that is assigned the function body and eventually when the class invokes the event, it will call the method.

If you dont want to do stuffs like this on every class, you can easily create an EventInvoker which defines each of them, and in the constructor of it you pass the delegate.

public class EventInvoker
{
   public EventInvoker(EventHandler<EventArgs> eventargs)
   {
      //set the delegate. 
   } 

   public void InvokeEvent()
   {
        // Invoke the event. 
   }
}

So basically you create a proxy class on each of those methods and making this generic will let you invoke events for any event. This way you can easily avoid making call to those properties every time.

abhishek
  • 2,975
  • 23
  • 38
  • Thank you, but what I can do with this Invoker class? As I mentioned C# does not have multi inheritance, so in 99% cases I cannot inherit from it (like MyWindow in WPF which inherits from Window already), and without it I am not able to invoke an event from Invoker. – greenoldman Sep 04 '10 at 15:48
  • No you dont inherit it, rather you create object of the class and use Event Accessor to pass the delegate to that class. – abhishek Sep 04 '10 at 16:04
  • If I read you right, it won't work. When you pass the list of listeners, all you get are the listeners at the moment of the passing them -- any later alteration won't be visible. See edit2. – greenoldman Sep 04 '10 at 19:00
  • How about building an Observer. Just as it does with Reactive Framework. – abhishek Sep 05 '10 at 11:30
1

Events are intended for being notified that something has happened. The class where event is declared takes care of triggering the event at the right time.

You couldn't cause something to happen by triggering an event from the outside, you would only cause every event subscriber to think that it had happened. The correct way to make something happen is to actually make it happen, not to make it look like it happened.

So, allowing events to be triggered from outside the class can almost only be misused. On the off chance that triggering an event from the outside would be useful for some reason, the class can easily provide a method that allows it.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • I cause something to happen by triggering an event from the outside. See edits. – greenoldman Sep 04 '10 at 15:49
  • 1
    @macias: No, triggering a PropertyChanged event doesn't cause the property to change. You are just trying to move the responsibility for triggering the event out of the class, which only makes the code harder to follow. – Guffa Sep 04 '10 at 16:34
  • So let's say that you made a `Button` class that raises a `Presssed` event when somebody clicks on it. Why is it bad to be able to create a subclass of `Button` that raises the `Pressed` event when somebody presses the Enter key? – Gabe Sep 04 '10 at 17:45
  • @Gabe: That would be OK as the class is a `Button`. Then you can follow the practice in the framework and create a method `protected virtual void OnPressed(EventArgs e)` that raises the event. – Guffa Sep 04 '10 at 19:54
  • Guffa: But that `OnPressed` function is only necessary because a subclass can't raise an event from its base class. I think the existence of the `OnXXX` convention is proof that there is a good use for raising an event from outside its class. – Gabe Sep 05 '10 at 00:56
1

Update

OK, before we go any further, we definitely need to clarify a certain point.

You seem to want this to happen:

class TypeWithEvents
{
    public event PropertyChangedEventHandler PropertyChanged;

    // You want the set method to automatically
    // raise the PropertyChanged event via some
    // special code in the EventRaisingType class?
    public EventRaisingType Property { get; set; }
}

Do you really want to be able to write your code just like this? This is really totally impossible -- at least in .NET (at least until the C# team comes up with some fancy new syntactic sugar specifically for the INotifyPropertyChanged interface, which I believe has actually been discussed) -- as an object has no notion of "the variables that have been assigned to me." In fact there is really no way to represent a variable using an object at all (I suppose LINQ expressions is a way, actually, but that's a totally different subject). It only works the opposite way. So let's say you have:

Person x = new Person("Bob");
x = new Person("Sam");

Does "Bob" know x just got assigned to "Sam"? Absolutely not: the variable x just pointed to "Bob", it never was "Bob"; so "Bob" doesn't know or care one lick about what happens with x.

Thus an object couldn't possibly hope to perform some action based on when a variable pointing to it gets changed to point at something else. It would be as if you wrote my name and address on an envelope, and then you erased it and wrote somebody else's name, and I somehow magically knew, @macias just changed the address on an envelope from mine to someone else's!

Of course, what you can do is modify a property so that its get and set methods modify a different property of a private member, and link your events to an event supplied by that member (this is essentially what siride has suggested). In this scenario it would be kind of reasonable to desire the functionality you're asking about. This is the scenario that I have in mind in my original answer, which follows.


Original Answer

I wouldn't say that what you're asking for is just flat-out wrong, as some others seem to be suggesting. Obviously there could be benefits to allowing a private member of a class to raise one of that class's events, such as in the scenario you've described. And while saurabh's idea is a good one, clearly, it cannot always be applied since C# lacks multiple inheritance*.

Which gets me to my point. Why doesn't C# allow multiple inheritance? I know this might seem off-topic, but the answers to this and that question are the same. It isn't that it's illegal because it would "never" make sense; it's illegal because there are simply more cons than pros. Multiple inheritance is very hard to get right. Similarly, the behavior you are describing would be very easy to abuse.

That is, yes, the general case Rex has described makes a pretty good argument against objects raising other objects' events. The scenario you've described, on the other hand -- the constant repetition of boilerplate code -- seems to make something of a case in favor of this behavior. The question is: which consideration should be given greater weight?

Let's say the .NET designers decided to allow this, and simply hope that developers would not abuse it. There would almost certainly be a lot more broken code out there where the designer of class X did not anticipate that event E would be raised by class Y, way off in another assembly. But it does, and the X object's state becomes invalid, and subtle bugs creep in everywhere.

What about the opposite scenario? What if they disallowed it? Now of course we're just considering reality, because this is the case. But what is the huge downside here? You have to copy and paste the same code in a bunch of places. Yes, it's annoying; but also, there are ways to mitigate this (such as saurabh's base class idea). And the raising of events is strictly defined by the declaring type, always, which gives us much greater certainty about the behavior of our programs.

So:

EVENT POLICY                  | PROS                | CONS
------------------------------+---------------------+-------------------------
Allowing any object to raise  | Less typing in      | Far less control over
another object's event        | certain cases       | class behavior, abun-
                              |                     | dance of unexpected 
                              |                     | scenarios, proliferation
                              |                     | of subtle bugs
                              |                     |
------------------------------------------------------------------------------
Restricting events to be only | Much better control | More typing required
raised by the declaring type  | of class behavior,  | in some cases
                              | no unexpected       |
                              | scenarios, signifi- |
                              | cant decrease in    |
                              | bug count           |

Imagine you're responsible for deciding which event policy to implement for .NET. Which one would you choose?

*I say "C#" rather than ".NET" because I'm actually not sure if the prohibition on multiple inheritance is a CLR thing, or just a C# thing. Anybody happen to know?

Community
  • 1
  • 1
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • The only problem with your table is (THANK YOU) that you are mixing people. Yes. I am punished because Joe Doe does not know how to write program. I strongly support the idea "everything should be doable, easy things easily, odd ones -- with difficulty". Forbidding something in advance is slight sign of vanity, because from time perspective it means "we predicted every possible use". I don't believe in such vast anticipation. And in regard to this issue -- I didn't use many dangerous features ($_ in Perl, anyone) and I wouldn't be addict for this too :-) – greenoldman Sep 04 '10 at 19:13
  • @macias: Firstly, "mixing people" is unavoidable, is it not? Every developer cannot have his/her own programming language with its own set of rules. Secondly, your philosophy for what a programming language should be is not the same as the C# philosophy. Once again the question comes down to pros and cons. By being widely accessible and feature-rich while restricting usage in ways that are designed to protect the average (sometimes careless) developer, C# has become an incredibly popular and useful language. They could've made it less rigid, and more buggy programs would've been written. – Dan Tao Sep 04 '10 at 19:19
  • Popularity has nothing to do with quality. The second, when you look at C# framework you will notice that despite the hype about being statically typed it is actually very dynamic languages, magical literal are flying around all the time (for in example in XAML). But triggering change events are good example as well. There is no nameof(MyProperty) only "MyProperty" (yes, I know the workaround), so IMHO C# is far, far away from being solid, bullet-proof language. – greenoldman Sep 04 '10 at 19:41
  • Now, about the update -- the last paragraph of your update is EXACTLY my case. Maybe I add it just for the record. Please, see edit 4 -- I hope we both think about the same thing. – greenoldman Sep 04 '10 at 19:43
  • @macias: In response to your first comment, I really think you're getting it backwards. Quality is precisely what these restrictions are in place to *improve* by eliminating scenarios that are likely to lead to bugs. Suppose I had some bizarre genetic condition where I could drink an unlimited amount of alcohol and still be a completely safe driver. It would be absurd for me to argue, "This law against drunk driving is a bad law! **I** can drive just fine after drinking; don't punish me for what others shouldn't do!" By making it illegal, a ton of fatal accidents are prevented. – Dan Tao Sep 04 '10 at 19:56
  • @macias: On the other hand, as my table is meant to illustrate, the opposite scenario brings with it not *nearly* enough benefit to counteract the associated costs. To continue my analogy: what if they legalized driving while intoxicated? On the plus side, I would no longer be inconvenienced when I decided to drive myself home from a bar. The downside would be that there would suddenly be a lot more car accidents, and a lot of people dying. In the case of .NET event invocation, I really think it's a similarly *unbalanced* trade off. Clearly you disagree with me; but I think that's the idea. – Dan Tao Sep 04 '10 at 20:00
  • Just for clarification -- I prefer writing general sender (class, not just interface) but since it is impossible in C# I am looking for other solutions. And on the other hand, if the language insist on copying&pasting some code instead of putting it into some basic function/class, it is sign of bad design of the language. – greenoldman Sep 05 '10 at 10:50
  • @macias: there will always be boilerplate. Even with a general sender, you'd have to write code in each property. Now, one option is to use PostSharp to weave in code that sends the event whenever any property is changed. You'd only have to do that once and then specify which classes you want it to apply to. To be perfectly honest, this may be the best solution for you. – siride Sep 05 '10 at 14:37
  • @Siride, now I don't have to write code for each property. I already skipped that -- see my edits, I embed each property in sender class, which is simply notifier. So I create it, and it does the rest. Btw. it is really odd, how WPF is designed that it listens to source container for change, but it ignores the source itself. – greenoldman Sep 06 '10 at 09:02
  • @macias: There is a huge difference between (1) a language being *designed to require* that you copy & paste code to accomplish a certain pattern, and (2) that language being *designed to protect* you from doing something dangerous. In the case of C# the design decision is aimed at the latter. There simply isn't (yet) a language feature in place to reduce the copying & pasting required in this particular scenario. That said, some creative alternative approaches have already been proposed by others. But don't just say "bad design" unless you've figured out a way to solve (1) without losing (2). – Dan Tao Sep 06 '10 at 22:14
  • @Dan, as you know there is no unbreakable protection -- it applies to hardware, software, and language too. No matter what language you consider there will be always a moron, who would write complete mess. I prefer languages that helps **me** keep **my** code clean, and warn me about dangers but allow me do this. For a wise developer, warning is enough, but with prohibiting this or that usage you are limiting the potential of the possible expressions. We mature for a reason, keeping it "safe" (by prohibiting things) is making a a toy, not a tool. – greenoldman Sep 07 '10 at 07:46
  • @macias: Yes, but much more common than *morons* are actually *pretty smart developers* who nonetheless misunderstand how something works or simply don't care that a certain way of doing things is inadvisable, because it does what they want and they just want to move forward. Neither C# nor any other language is going to protect the world from morons; but it can help those developers who might otherwise do something iffy (e.g., raising another object's event) by having mechanisms in place which strongly promote better strategies. – Dan Tao Sep 07 '10 at 07:57
  • @macias: As for your case, this hardly even seems relevant anymore as the solution you seem to have settled upon in your question is also the most obvious one: have a type expose a public method that basically *amounts to* raising a specific event. I mean, that's pretty much all you wanted to do anyway, right? So is C# really even keeping you from doing what you want anymore? It doesn't seem like it. – Dan Tao Sep 07 '10 at 07:59