取消装箱后无法访问类的成员

时间:2013-09-20 13:04:46

标签: c# events object unboxing

我正在学习高级C#。在下面的代码中,我正在尝试进行事件处理

我在取消装箱后访问班级发件人的成员时收到错误          //编译器不允许我使用这些名称

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

为什么会这样? 这就是我们所说的拳击和拆箱,如果我不会感到困惑。

在我迄今为止所做的所有示例中,都有事件类继承EventArgs。该课程需要什么。虽然在这里我没有使用过这个课程,但我直接使用了Eventargs(只是制作了它)。

      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();

            }
        }
    }

善意评论我的编码样式和含糊之处。在此先感谢

3 个答案:

答案 0 :(得分:8)

这是问题所在:

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

第二行不会更改obj编译时类型。它仍然只是object。 (而你创建新object的第一行完全没有意义。)当你尝试使用obj时,编译器并不关心你对obj.name做了什么 - 它关心的是编译时类型。你想要:

Sender obj = (Sender) sender;

(请参阅我的recent blog post,了解为什么演员比在此使用as更合适。)

想要使用公共属性而不是私有字段:

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

请注意,此播放取消装箱,顺便说一下 - 您没有涉及任何值类型(Sender是一个类),因此不涉及装箱或拆箱。

答案 1 :(得分:2)

您的问题是,您假设obj=sender as Sender;会更改obj的类型。它不会。它将保持声明它的类型,即object。这里:object obj = new object();

替换:

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

使用:

var obj = sender as Sender;

或者你可以投它:

((Sender)obj).MySenderProperty

答案 2 :(得分:0)

使用Sender作为类名是一个坏主意,但以下是获取类Sender对象的正确方法:

Sender obj = sender as Sender;

但就像我说的那样我永远不会这样做,避免使用常见的名称,例如你的例子中的“对象发送者”。