CS0120: Uma referência de objeto é necessária para o campo não estático, método ou propriedade '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 que esse erro está ocorrendo?

Uma referência de objeto é necessária para o campo, método ou propriedade não estático 'WindowsApplication1.Form1.setTextboxText (int)

Respostas:


401

Parece que você está chamando um membro não estático (uma propriedade ou método, especificamente setTextboxText) de um método estático (especificamente SumData). Você precisará:

  1. Torne o membro chamado estático também:

    static void setTextboxText(int result)
    {
        // Write static logic for setTextboxText.  
        // This may require a static singleton instance of Form1.
    }
  2. Crie uma instância Form1dentro do método de chamada:

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

    Passar em uma instância de Form1seria uma opção também.

  3. Torne o método de chamada um método de instância não 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);
    }

Mais informações sobre esse erro podem ser encontradas no MSDN .


18

Você inicia um thread que executa o método estático SumData. No entanto, SumDatachamadas SetTextboxTextque não são estáticas. Portanto, você precisa de uma instância do seu formulário para chamar SetTextboxText.


13
Esta resposta parece reafirmar o problema. Não explica por que isso produz um erro.
Robert

13

Nesse caso, onde você deseja obter um controle de um formulário e está recebendo esse erro, tenho um pequeno desvio para você.

Vá para o seu Program.cs e altere

Application.Run(new Form1());

para

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

Agora você pode acessar um controle com

Program.form1.<Your control>

Além disso: não se esqueça de definir seu nível de acesso de controle como público.

E sim, eu sei, essa resposta não se encaixa no chamador de perguntas, mas se aplica aos googlers que têm esse problema específico com os controles.


6

Seu método deve ser estático

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

Esse método específico acessa explicitamente as propriedades da instância (especificamente this.InvokeRequirede this.Invoke) e, portanto, não pode ser tornado estático.
dbc 31/03

2

Agradecemos a @COOLGAMETUBE por me informar sobre o que acabou funcionando para mim. Sua ideia foi boa, mas tive um problema quando o Application.SetCompatibleTextRenderingDefault foi chamado depois que o formulário já foi criado. Então, com uma pequena mudança, isso está funcionando para mim:


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

1

Do meu ponto de vista, você atribui um valor nulo a uma caixa de texto e retorna em um ToString()como é um método estático. Você pode substituí-lo por Convert.ToString()que pode ativar o valor nulo.


0

Na verdade, eu recebi esse erro porque estava verificando o InnerHtml em busca de algum conteúdo gerado dinamicamente - ou seja, um controle que é runat = server.

Para resolver isso, tive que remover a palavra-chave "estática" no meu método, e ela correu bem.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.