accessing an instance in main from a form

2019-09-07 06:46发布

问题:

/* Hi i am trying to make my first c# application on visual studio. I have created a class and an instance of that class in main and i am simply trying to query a member of that instance inside a click event on a form but its telling me the instance name does not exist in the current context. Any help would be appreciated here's my code. */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;

    namespace WindowsFormsApplication10
    {

     public class character         // this is my class
        {
            public bool hair_black;
        }


        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());

                character deviljin = new character();  // instance of my class

                deviljin.hair_black = true;      // initiating a member of the instance


            }
        }
    }

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication10
    {


        public partial class Form1 : Form
        {

            int cs1 = 0,cs2=0;


            public Form1()
            {
                InitializeComponent();


            public void pictureBox1_Click(object sender, EventArgs e)
            {

                flowLayoutPanel1.Visible = true;
                if (deviljin.hair_black == true)   // trying to access instance member
                {                                  // but getting deviljin does not
                                                   // exist in the current context
                    pictureBox28.Visible = false;
                }            

            }

        }
    }

回答1:

You would need to update your Form to take an instance of Character as a parameter e.g.

public partial class Form1 : Form
{
    private Character _character;
    public Form1(Character character)
    {
        _character = character;
    }

    public void pictureBox1_Click(object sender, EventArgs e)
    {
        If (_character.hair_black)
        {
             ...
        }
    }
}
...
var deviljin = new Character()
{
    hair_black = true
};
Application.Run(new Form1(deviljin));


回答2:

This is because of what the error says - the instance doesn't exist in the current context (the context of the form)

It's a scope issue - every variable you declare has a scope and since you are declaring your character class instance in the local scope of the Main method in the Program class, it will only be visible in that method.

Since the Program class is static, you could just create a static member on that class e.g.:

namespace WindowsFormsApplication10
{

 public class character         // this is my class
    {
        public bool hair_black;
    }


    static class Program
    {
        public static character deviljin;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

EDIT: didn't really notice this, but as Steve pointed out, whilst this will compile, if you call Application.Run before you instantiate the variable you will get a runtime exception when trying to access it (it will be null) so make sure you do this before Application.Run

            deviljin = new character();  // instance of my class

            deviljin.hair_black = true;      // initiating a member of the instance

            Application.Run(new Form1());


        }
    }
}

This way you can access your instance via the Program class:

        public void pictureBox1_Click(object sender, EventArgs e)
        {

            flowLayoutPanel1.Visible = true;
            if (Program.deviljin.hair_black == true)   
            { 
                pictureBox28.Visible = false;
            }            

        }

Read up on variable scope, access modifiers and static/instance variables - for a very simple project, static variables can be ok so you can go this route whilst you are still learning



回答3:

Your instance variable deviljin is local to the main method and cannot be directly referenced outside of that method.

You need to pass the reference inside the instance of Form1 where you are trying to use it. This could be done passing the reference directly via the constructor of form1

 Application.Run(new Form1(deviljin));

and of course changing the constructor of Form1 to

private character _devReferenceToCharacterPassed

public Form1(character mycharInstance)
{
    _devReferenceToCharacterPassed = mycharInstance;
    InitializeComponent();
}

now you can use the passed in instance in your click code

public void pictureBox1_Click(object sender, EventArgs e)
{
    flowLayoutPanel1.Visible = true;
    if (_devReferenceToCharacterPassed.hair_black == true)   
    {                                  
         pictureBox28.Visible = false;
    }            
}

also take note that

Application.Run(new Form1(deviljin));

is a blocking call. It means that your code doesn't exit from this call till the Form1 is open, so you need to move the creation of the deviljin variable before the Run call.

EDIT: I'm strongly opposed to use of variables with global visibility across an application. Sometimes they are necessary, but they lead to the creation of unmaintainable code very quickly. It 'better to learn to program with the fewest possible global variables