CS0120: จำเป็นต้องมีการอ้างอิงวัตถุสำหรับฟิลด์เมธอดหรือคุณสมบัติ 'foo'


274

พิจารณา:

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

ทำไมข้อผิดพลาดนี้เกิดขึ้น

จำเป็นต้องมีการอ้างอิงวัตถุสำหรับฟิลด์เมธอดหรือคุณสมบัติ 'WindowsApplication1.Form1.setTextboxText (int)

คำตอบ:


401

ดูเหมือนว่าคุณกำลังเรียกสมาชิกที่ไม่คงที่ (คุณสมบัติหรือวิธีการเฉพาะsetTextboxText) จากวิธีการคงที่ (โดยเฉพาะSumData) คุณจะต้อง:

  1. ทำให้สมาชิกที่เรียกว่าคงที่:

    static void setTextboxText(int result)
    {
        // Write static logic for setTextboxText.  
        // This may require a static singleton instance of Form1.
    }
  2. สร้างตัวอย่างของForm1ภายในวิธีการโทร:

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

    การส่งผ่านตัวอย่างForm1จะเป็นตัวเลือกเช่นกัน

  3. ทำให้วิธีการเรียกใช้เป็นวิธีการแบบไม่คงที่ (จาก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);
    }

ข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดนี้สามารถพบได้ใน MSDN


18

SumDataคุณเริ่มต้นด้ายซึ่งไหลวิธีการแบบคงที่ อย่างไรก็ตามการSumDataโทรSetTextboxTextที่ไม่คงที่ SetTextboxTextดังนั้นคุณจะต้องเป็นตัวอย่างของแบบฟอร์มของคุณเรียก


13
คำตอบนี้ปรากฏขึ้นเพื่อแก้ไขปัญหา ไม่ได้อธิบายว่าทำไมสิ่งนี้จึงทำให้เกิดข้อผิดพลาด
Robert

13

สำหรับกรณีนี้ที่คุณต้องการได้รับการควบคุมของแบบฟอร์มและได้รับข้อผิดพลาดนี้จากนั้นฉันมีการบายพาสเล็กน้อยสำหรับคุณ

ไปที่ Program.cs ของคุณและเปลี่ยน

Application.Run(new Form1());

ถึง

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

ตอนนี้คุณสามารถเข้าถึงตัวควบคุมด้วย

Program.form1.<Your control>

นอกจากนี้อย่าลืมตั้งค่าการควบคุมการเข้าถึงระดับเป็นสาธารณะ

และใช่ฉันรู้ว่าคำตอบนี้ไม่เหมาะกับผู้ที่ถามคำถาม แต่เหมาะสำหรับชาว Google ที่มีปัญหาเฉพาะกับตัวควบคุม


6

วิธีการของคุณจะต้องคงที่

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

วิธีการเฉพาะนี้เข้าถึงคุณสมบัติของอินสแตนซ์อย่างชัดเจน (โดยเฉพาะthis.InvokeRequiredและthis.Invoke) และไม่สามารถทำแบบคงที่ได้
dbc

2

ขอมอบเครดิตให้แก่ @COOLGAMETUBE สำหรับการให้ทิปกับสิ่งที่ทำให้ฉันทำงานได้ ความคิดของเขาดี แต่ฉันมีปัญหาเมื่อ Application.SetCompatibleTextRenderingDefault ถูกเรียกหลังจากฟอร์มถูกสร้างขึ้นแล้ว ดังนั้นเมื่อมีการเปลี่ยนแปลงเล็กน้อยสิ่งนี้ใช้ได้กับฉัน:


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

จากการมองของฉันคุณให้ค่า null กับกล่องข้อความและส่งกลับค่า a ToString()เนื่องจากเป็นวิธีแบบคงที่ คุณสามารถแทนที่ด้วย Convert.ToString()ที่สามารถเปิดใช้งานค่า Null


0

ที่จริงฉันได้รับข้อผิดพลาดนี้เพราะฉันกำลังตรวจสอบ InnerHtml สำหรับเนื้อหาบางส่วนที่สร้างขึ้นแบบไดนามิก - นั่นคือการควบคุมที่ runat = เซิร์ฟเวอร์

เพื่อแก้ปัญหานี้ฉันต้องลบคำหลัก "คงที่" ในวิธีการของฉันและมันก็ทำงานได้ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.