1

I am learning advanced C#.In the following Code i am trying to do Event handling

i get Error while accessing members of class sender after unboxing //Compiler is not letting me use these names

//    Console.WriteLine("Sender is {0} and message is {1}",obj.name,obj.messgae);

Why is that so? Is that what we call boxing and unboxing, if i am not getting confused.

In all examples i have done so far, there is event class inheriting EventArgs. What is need of that class .Although here i have not used this class instead i have used Eventargs directly(just made it).

      namespace ConsoleApplication5
    {
        class eventclass : EventArgs
        {
            string var;
        }
        delegate void GenerateEvent(object source, EventArgs e);
        class Sender
        {
            public void MyMethod()
            {
                Console.WriteLine("My method Called");

            }
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                }
            }

            private string message;
            public string Message
            {
                get
                {
                    return message;
                }
                set
                {
                    message = value;
                }
            }
            public event GenerateEvent OnAlert;

            public void Sendit()
            {
                Console.WriteLine("Sender: Sending Message Now");
                OnAlert(this, new EventArgs());
                Console.WriteLine("Sender: Message Sent");

            }
        }
        class Receiver
        {
            public static void ReceiveMsg(object sender, EventArgs e)
            {
                Console.WriteLine("Receiveing Message");
                object obj = new object();
                obj = sender as Sender;

                /*Here i get Error while accessing members of class sender after unboxing 
                //Compiler is not letting me use these names
                //    Console.WriteLine("Sender is {0} and message is {1}",obj.name,obj.messgae);

                */


                Console.WriteLine("Received" + obj.GetType());
            }

        }
        class Program
        {
            static void Main(string[] args)
            {
                Receiver r = new Receiver();
                Sender s = new Sender();
                s.OnAlert += new GenerateEvent(Receiver.ReceiveMsg);
                s.Sendit();

            }
        }
    }

kindly comment about my Coding Styles and ambiguities. Thanks in Advance

Charlie
  • 4,827
  • 2
  • 31
  • 55
  • 1
    "kindly comment about my Coding Styles and ambiguities" - In those cases where you have working code, [CodeReview.SE](http://codereview.stackexchange.com/) is a great place to ask for advice on how to clean up your code. – Brian Sep 20 '13 at 13:51

3 Answers3

8

This is the problem:

object obj=new object();
obj=sender as Sender;

The second line doesn't change the compile-time type of obj. It's still just object. (And your first line that creates a new object is completely pointless.) The compiler doesn't care what you've done with obj when you try to use obj.name - it cares about the compile-time type. You want:

Sender obj = (Sender) sender;

(See my recent blog post about why the cast is preferable over using as here.)

You also want to use the public properties rather than the private fields:

Console.WriteLine("Sender is {0} and message is {1}", obj.Name, obj.Message);

Note that this casting is not unboxing, by the way - you have no value types involved (Sender is a class) so there's no boxing or unboxing involved.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yes it works but what if we get the object of unknown class . – Charlie Sep 20 '13 at 13:15
  • 1
    @Charlie: Then how would you know what properties you'd want to use anyway? You could use `dynamic` instead, or if you have multiple classes with the same properties/methods in common, consider using an interface. – Jon Skeet Sep 20 '13 at 13:16
  • Well this casting thing is clear but Unboxing thing is still confusing , if i add values in object and extract the values back ,its same what i was going to do why not worked.How to do unboxing then – Charlie Sep 20 '13 at 13:24
  • @Charlie: It's not at all clear what you mean (particularly in "if i add values in objet and extract the values back, its same what i was going to do why not worked"), but you should read the page I linked to - what you're terming "unboxing" is *not* unboxing. – Jon Skeet Sep 20 '13 at 13:25
  • @Charlie: Please erase `dynamic` from your mind and ignore Jon's suggestion to use it. While it can be used to solve certain types of problems, usually other solutions are better. Don't give in to the temptation to abuse `dynamic`. 99% of the time, either your design is faulty or you need to add some interfaces. E.g., changing your declaration to `dynamic obj = new object()` would work, but would slow down your program, kill autocomplete, and turn easily fixed compile time errors into runtime errors. – Brian Sep 20 '13 at 13:39
  • @Brian: I wasn't intending to really recommend using `dynamic` - just giving it as an option. Frankly we don't really know the OP's requirements at the moment, which makes it hard to help. I don't like `dynamic` either in most cases, but it *might* be what the OP needs. – Jon Skeet Sep 20 '13 at 13:41
  • 1
    @JonSkeet: Honestly, unless they're in a situation where it is obviously appropriate, I prefer to avoid even giving `dynamic` as an option to new programmers, especially without a disclaimer. It has the bad combination of rarely being good choice yet frequently being an easy choice (in the short term). – Brian Sep 20 '13 at 13:49
  • @Brian: Yes, that's true. In retrospect I think I'd probably have *mentioned* it (rather than inaccurately claim it's impossible) but give a strong caveat. – Jon Skeet Sep 20 '13 at 13:52
2

Your issue is that you're assuming obj=sender as Sender; will change the type of obj. It will not. It will remain the type from which it was declared, which is object. Here: object obj = new object();

Replace:

object obj = new object();
obj= sender as Sender;

with:

var obj = sender as Sender;

Or you can just cast it:

((Sender)obj).MySenderProperty
Khan
  • 17,904
  • 5
  • 47
  • 59
0

It is a bad idea to use Sender as a class name, but the follow would be the correct way to get a object of class Sender:

Sender obj = sender as Sender;

But like I said I would never do this avoid names that are commonly used like in "object sender" in your example.

Bit
  • 1,068
  • 1
  • 11
  • 20
  • 2
    There's nothing wrong with `Sender` as a class name. `sender` is merely the name of a parameter in the "standard" `EventHandler` model. – Moo-Juice Sep 20 '13 at 13:14
  • I disagree it is commonly used for given use and using it for something else causes confusion it is bad practice and bad programming. – Bit Sep 20 '13 at 13:16
  • @N4TKD: If "Sender" is the best description for what the class does, I have no problem with using it for a class name. Lots of terms are contextual. For example, in a calendar app you may well have an `Event` class - and you'd expect developers to understand that's not the same kind of event as a C# event. – Jon Skeet Sep 20 '13 at 13:18
  • @N4TKD, if you can't tell the difference between `Sender` and `sender` as a parameter name, there are issues. This may have been a point in the days when there were no IDEs. But these days, it's pretty obvious. Anyway, we must agree to disagree ;) – Moo-Juice Sep 20 '13 at 13:18
  • @Moo-Juice I do disagree I believe you should be able to read your code like a book and have no miss understanding about its meaning. I use my IDE as a tool but I do not lean on it to the point my code is not readable. I am a big believer in "Clean Code." – Bit Sep 20 '13 at 13:25
  • 1
    @N4TKD, I am a big believer in clean code too :) But I can also tell the difference between `Sender` and `sender`, given that all my parameters are lower-case and *all* my classes, enums, interfaces, events, and properties have an upper-case. – Moo-Juice Sep 20 '13 at 13:26