CS0120: Se requiere una referencia de objeto para el campo no estático, método o propiedad 'foo'

274

Considerar:

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //int[] val = { 0, 0};
            int val;
            if (textBox1.Text == "")
            {
                MessageBox.Show("Input any no");
            }
            else
            {
                val = Convert.ToInt32(textBox1.Text);
                Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
                ot1.Start(val);
            }
        }

        private static void ReadData(object state)
        {
            System.Windows.Forms.Application.Run();
        }

        void setTextboxText(int result)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
            }
            else
            {
                SetTextboxTextSafe(result);
            }
        }

        void SetTextboxTextSafe(int result)
        {
            label1.Text = result.ToString();
        }

        private static void SumData(object state)
        {
            int result;
            //int[] icount = (int[])state;
            int icount = (int)state;

            for (int i = icount; i > 0; i--)
            {
                result += i;
                System.Threading.Thread.Sleep(1000);
            }
            setTextboxText(result);
        }

        delegate void IntDelegate(int result);

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

¿Por qué ocurre este error?

Se requiere una referencia de objeto para el campo, método o propiedad no estático 'WindowsApplication1.Form1.setTextboxText (int)

huda
fuente

Respuestas:

401

Parece que está llamando a un miembro no estático (una propiedad o método, específicamente setTextboxText) desde un método estático (específicamente SumData). Necesitará:

  1. Haga que el miembro llamado también sea estático:

    static void setTextboxText(int result)
    {
        // Write static logic for setTextboxText.  
        // This may require a static singleton instance of Form1.
    }
  2. Cree una instancia Form1dentro del método de llamada:

    private static void SumData(object state)
    {
        int result = 0;
        //int[] icount = (int[])state;
        int icount = (int)state;
    
        for (int i = icount; i > 0; i--)
        {
            result += i;
            System.Threading.Thread.Sleep(1000);
        }
        Form1 frm1 = new Form1();
        frm1.setTextboxText(result);
    }

    Pasar en una instancia de Form1sería una opción también.

  3. Convierta el método de llamada en un método de instancia no estático (de Form1):

    private void SumData(object state)
    {
        int result = 0;
        //int[] icount = (int[])state;
        int icount = (int)state;
    
        for (int i = icount; i > 0; i--)
        {
            result += i;
            System.Threading.Thread.Sleep(1000);
        }
        setTextboxText(result);
    }

Se puede encontrar más información sobre este error en MSDN .

dbc
fuente
18

Comienza un hilo que ejecuta el método estático SumData. Sin embargo, SumDatallamadas SetTextboxTextque no son estáticas. Por lo tanto, necesita una instancia de su formulario para llamar SetTextboxText.

Brian Rasmussen
fuente
13
Esta respuesta parece reafirmar el problema. No explica por qué esto produce un error.
Robert
13

Para este caso, donde desea obtener un Control de un formulario y recibe este error, entonces tengo un pequeño bypass para usted.

Vaya a su Program.cs y cambie

Application.Run(new Form1());

a

public static Form1 form1 = new Form1(); // Place this var out of the constructor
Application.Run(form1);

Ahora puede acceder a un control con

Program.form1.<Your control>

Además: no olvide establecer su Nivel de acceso de control en Público.

Y sí, lo sé, esta respuesta no se ajusta a la persona que llama, pero sí a los googlers que tienen este problema específico con los controles.

COOLGAMETUBE
fuente
6

Tu método debe ser estático

static void setTextboxText(int result)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result }); 
    }
    else
    {
        SetTextboxTextSafe(result);
    }
}
issam chouchane
fuente
Este método específico accede explícitamente a las propiedades de instancia (específicamente this.InvokeRequiredy this.Invoke) y, por lo tanto, no puede hacerse estático.
DBC
2

Gracias a @COOLGAMETUBE por informarme de lo que terminó funcionando para mí. Su idea era buena, pero tuve un problema cuando se llamó a Application.SetCompatibleTextRenderingDefault después de que el formulario ya se había creado. Entonces, con un pequeño cambio, esto está funcionando para mí:


static class Program
{
    public static Form1 form1; // = new Form1(); // Place this var out of the constructor

/// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(form1 = new Form1()); } }
veggiebenz
fuente
1

Desde mi punto de vista, le da un valor nulo a un cuadro de texto y devuelve un ToString()ya que es un método estático. Puede reemplazarlo con Convert.ToString()eso puede habilitar el valor nulo.

Abd Al-Kareem Attiya
fuente
0

De hecho, recibí este error porque estaba buscando en InnerHtml algún contenido generado dinámicamente, es decir, un control que es runat = server.

Para resolver esto, tuve que eliminar la palabra clave "estática" en mi método, y funcionó bien.

Max Alexander Hanna
fuente