Locked Variable Scope and static Fields in Forms

  • Friday, February 17, 2012 12:08 AM
     
      Has Code

    Forms Applications.

    As I understand it the scope of a variable depends on where it is declared and the private/public modifier (defaulting to private if no modifier used). If a variable is declared private in a Form class it has scope throught that class and class methods. If it is public in addition it will have scope in other classes in the project. I made a program to test is as below:

    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 ScopeTest
    {
        public partial class Form1 : Form
        {
            public static string strTest = "Test";  // LABEL 1
    
            public Form1()
            {
                
                InitializeComponent();
    
                Testit();
                MyClass.Testit2();
            }
    
           
    
            public void Testit()
            {
                MessageBox.Show(strTest);        // LABEL 2
            }  
        }
    
        public static class MyClass
        {
            public static void Testit2()
            {
                MessageBox.Show(Form1.strTest);  // LABEL 3
                
            }
        }
    }

    This works and as expected the variable at LABEL 1 is visible to the Form1 method at LABEL 2 and the method in the separate class at LABEL 3.
    If the line at LABEL 1 is changed to
    private static string strTest = "Test";
    as expected there is a compile error at LABEL 3 "ScopeTest.Form1.strTest' is inaccessible due to its protection level".
    But if the line at LABEL 1 is changed to
    public string strTest = "Test";
    so that variable strTest is no longer static there is a compile error at LABEL 3 "An object reference is required for the non-static field, method, or property 'ScopeTest.Form1.strTest".
    This is not a scope error but why does the variable need to be static?


    Peter



    • Edited by peterwt Friday, February 17, 2012 12:12 AM
    •  

All Replies

  • Friday, February 17, 2012 12:12 AM
     
      Has Code

    "This is not a scope error but why does the variable need to be static?"

    The variable needs to be static to be used this way because you're accessing it via the Form1 class, not via an instance of a Form1.

    When you make a variable static, it causes it to "belong" to the type itself, in this case, Form1.  When it's not static, it "belongs" to the instance of a class you create.  For example, if you create a Form1, you'd be able to access the variable within that instance.

    You can see this by making it non-static (and public).  To get this to work, you would then need to do:

     public static class MyClass
        {
            public static void Testit2()
            {
                // Create an instance of Form1
                Form1 theForm = new Form1();
    
                // Now access the variable on that instance, not via the class
                MessageBox.Show(theForm.strTest);  // LABEL 3
                
            }
        }


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

  • Friday, February 17, 2012 12:56 AM
     
     

    Thanks Reed - I see. I was under the impression that the line in the Program.cs:-

    Application.Run(new Form1());

    created an instance of Form1. So in a single Form program there is never an instance of the form created unless it is specifically called.

    The one problem with your solution is it goes into a continious loop as calling an instance of Form1 causes the program code in Form1 to be called so it continiously repeats.

    Regards


    Peter

  • Friday, February 17, 2012 1:19 AM
     
      Has Code

    Thanks Reed - I see. I was under the impression that the line in the Program.cs:-

    Application.Run(new Form1());

    created an instance of Form1. So in a single Form program there is never an instance of the form created unless it is specifically called.

    The one problem with your solution is it goes into a continious loop as calling an instance of Form1 causes the program code in Form1 to be called so it continiously repeats.

    Regards


    Peter

    It does create the instance - it's kind of like writing:

    Form1 theMainForm = new Form1(); 
    Application.Run(theMainForm);

    However, to use an instance method, you'd need access to that instance, ie: the "theMainForm" variable.  In this case, it's just passed into Application.Run, and not available to you in other classes.

    The thing here is that you can make as many instances of Form1 as you want - you can have 3 "form1" instances opened at once (which would show 3 forms on your screen), and call an instance method on a specific one of those.  Static methods are owned by the type itself, not one object of that type.

    I am aware that my code doesn't "really" work - in your case, if you wanted to use an instance method, you could do this (which should work):

        public partial class Form1 : Form
        {
            public string strTest = "Test";  // LABEL 1
    
            public Form1()
            {
                
                InitializeComponent();
    
                Testit();
    
                // Pass "this" instance to the method!
                MyClass.Testit2(this);
            }
    
           
    
            public void Testit()
            {
                MessageBox.Show(strTest);        // LABEL 2
            }  
        }
    
        public static class MyClass
        {
            public static void Testit2(Form1 theForm)
            {
                // This now works on a specific instance
                MessageBox.Show(theForm.strTest);  // LABEL 3
                
            }
        }


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

  • Saturday, February 18, 2012 3:10 PM
     
     

    Thanks Reed - I understand now.

    I couldn't see how the instance of the form was created - it must have been to be visible!!

    As you showed its in the Program.cs line:- Application.Run(new Form1());

    When an instance of a form is created using

    Form1 f1 = new Form1();

    we have f1 to refer to Form1, but is not available in Application.Run(new Form1()); but is available as this.

    When this reference is used in - public static void Testit2(Form1 f1) - the argument for Testit2(Form1 f1) takes the form (variable type - variable name) so the variable f1 is type Form1.

    What type of variable is this?


    Peter

  • Saturday, February 18, 2012 5:16 PM
     
     Answered

    It's a reference to an instance of a Form1 - Form1 is a class therefore a type.

    Or have I misunderstood?


    Regards David R
    ---------------------------------------------------------------
    Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
    Every program eventually becomes rococo, and then rubble. - Alan Perlis
    The only valid measurement of code quality: WTFs/minute.

    • Marked As Answer by peterwt Sunday, February 19, 2012 10:47 AM
    •