2012-05-22 4 views
-1

In a previous question Я спросил о сообщении об ошибке заголовка темы, и ответ был почти ослепительно очевидным.«Требуется ссылка на объект для нестатического поля»

Однако этот пример «сварил» был из некоторого кода, который был не совсем разбавлен, и теперь исходный вопрос появляется снова в моем новом бульоне.

Я подозреваю, что может быть открытие себя до много «интересных» комментариев, но эй ... нет таких вещей, как глупые вопросы, только тупые программисты!»

Во всяком случае, вот только немного вареная версия оригинального кода:

public partial class Form1 : Form 
{ 
    public static Form1 mForm = new Form1(); 


    // define textbox parameter structure 
    struct ParmStruct 
    { 
     public TextBox sTextBoxName; 
     public double dMinValue; 
     public double dMaxValue; 

     public ParmStruct(TextBox sTextBoxName, double dMinValue, double dMaxValue) 
     { 
      this.sTextBoxName = sTextBoxName; 
      this.dMinValue = dMinValue; 
      this.dMaxValue = dMaxValue; 
     } 
    } 

    // Create list of Parameters (name, min, max) 
    static ParmStruct[] ParmList = new ParmStruct[] 
    { 
     new ParmStruct { sTextBoxName = mForm.textBox1, dMinValue = -99, dMaxValue = 99 }, 
     new ParmStruct { sTextBoxName = textBox2, dMinValue = 0, dMaxValue = 100 } 
    }; 

    public Form1() 
    { 
     InitializeComponent(); 

     this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); 
    } 

    private void textBox1_TextChanged(object sender, EventArgs e) 
    { 
     TextBox tb1; 

     tb1 = mForm.textBox1; 
     tb1 = textBox2; 

     double x = ParmList[0].dMaxValue; 
    } 
} 

Вторая строка инициализации ParmList (sTextBoxName = textBox2) не будет компилироваться, если я не сделать его sTextBoxName = mForm.textBox2.

Однако линия tb1 = textBox2 будет компилировать и не требуется mForm. префикс.

Это фактический случай, который изначально вызвал путаницу (и до сих пор, насколько я знаю).

Не совсем уверен, почему компилятор (VS 2010) может понять это в одном случае, но не в другом.

Ох ... и код действительно работает при компиляции. :)

+0

Можете ли вы показать, где и как объявляются текстовые поля? – 3Pi

+0

@ 3Pi Вероятно, в 'Form1.Designer.cs' –

+0

Возможно, но предположения в программировании часто являются источником ошибок. Лучше убедиться, особенно с двумя объектами, которые должны вести себя одинаково, но не являются – 3Pi

ответ

0

textBox2 - это объект, который существует только в контексте mForm, поэтому вам придется обладать его как поле mForm, поскольку оно не было объявлено в вашем методе или в качестве [статического] объекта в вашем классе.

+0

Должен сказать, что у меня никогда не было ответов на мои вопросы где-то раньше в такой своевременной (и точной!) способ! – user1408942

+0

Он не существует * только * в контексте 'mForm'. Каждый экземпляр 'Form1' имеет свой собственный' textBox2'. –

+0

Это правда. Однако статический конструктор params не может получить какой-либо экземпляр textBox2, кроме того, который связан с mForm, поэтому с точки зрения конструктора списка он существует только в контексте mForm. – Kell

2

Это проблема.

// Create list of Parameters (name, min, max) 
static ParmStruct[] ParmList = new ParmStruct[] 
{ 
    new ParmStruct { sTextBoxName = mForm.textBox1, dMinValue = -99, dMaxValue = 99 }, 
    new ParmStruct { sTextBoxName = textBox2, dMinValue = 0, dMaxValue = 100 } 
}; 

Это не имеет никакого смысла для этой переменной будет распределяться между всеми экземплярами Form1 (что делает static ключевое слово), потому что каждый экземпляр формы имеет свой собственный уникальный textBox2. Кроме того, просто удаление ключевого слова static, как предложил Крис, также не является проблемой. Вы не можете ссылаться на textBox2, пока он не был создан, и это происходит внутри InitializeComponent (вызвано конструктором Form1). Это будет лучше:

// list of Parameters (name, min, max) 
ParmStruct[] ParmList; 

public Form1() 
{ 
    InitializeComponent(); 

    // now the textboxes exist and can be associated with the structure 
    ParmList = new ParmStruct[] { 
     new ParmStruct { sTextBoxName = textBox1, dMinValue = -99, dMaxValue = 99 }, 
     new ParmStruct { sTextBoxName = textBox2, dMinValue = 0, dMaxValue = 100 } 
    }; 

    this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); 
} 

Внутри как конструктор и textBox1_TextChanged метод, вы можете обратиться к textBox1 и textBox2 без какой-либо дополнительной квалификации, компилятор будет найти те, принадлежащие this объекта, так же, как если бы вы ввели this.textBox1 (см., например, последний пример конструктора). Компилятор НЕ будет использовать текстовые поля от mForm. На самом деле, нет никаких причин для статического поля mForm, так как нет кода для его отображения.

+0

+1 И вторая строка не требует ссылки на объект, потому что это неявно 'this'. –

+0

@Cicada: Вы имеете в виду подписку на «TextChanged»? Это идентично коду в вопросе, выглядит созданным дизайнером. –

+0

OP задавался вопросом, почему 'Однако, строка tb1 = textBox2 будет компилироваться и не требует mForm. prefix.' Я думаю, что хорошо объяснить, почему он компилируется (и не относится к полю mForm). OP думает, что компилятор * понял это *, но это не так. –

Смежные вопросы