Передача аргументов в C# и VB.NET

Можем ли мы в VB.NET передать исходный объект в качестве аргумента, не создавая его экземпляр? Например, у меня есть две формы в моем проекте formA и formB. Теперь у меня есть этот код.

Public Sub AddForm(Form Outer, Form Inner)
    Inner.FormBorderStyle = FormBorderStyle.None
    Inner.TopLevel = False;
    Inner.Dock = DockStyle.Fill
    Inner.WindowState = FormWindowState.Normal
    Outer.Controls.Add(Inner)
    Inner.BringToFront()
    Inner.Show()
End Sub

Теперь я могу использовать это в любом случае, например:

AddForm(formA, formB)

но ...

Взяв тот же код на C#

public static void AddForm(Form Outer, Form Inner)
{
    Inner.FormBorderStyle = FormBorderStyle.None;
    Inner.TopLevel = false;
    Inner.Dock = DockStyle.Fill;
    Inner.WindowState = FormWindowState.Normal;
    Outer.Controls.Add(Inner);
    Inner.BringToFront();
    Inner.Show();
} 

Я не могу назвать это так:

AddForm(formA, formB);

Это дает ошибку

formB является типом, но используется как переменная.

Вместо этого я должен называть это так:

AddForm(A, new B());

Кроме того, в VB.NET в любом классе, таком как formA, если я наберу formA, я смогу увидеть все объекты и элементы управления, присутствующие там, но не в C#. Опять же, мне нужно создать новый экземпляр, чтобы увидеть все элементы управления. Это становится проблемой, если я хочу манипулировать двумя запущенными и работающими экземплярами друг с другом. Итак, какую основную вещь я здесь упускаю?

(Я программист-любитель, переходящий с VB.NET на C#. Все идет хорошо и чисто, ожидая того, что я недавно понял.)


person Sami Ul Basit    schedule 14.01.2012    source источник
comment
Когда вы звоните, вы находитесь в FormA? Если да, вам нужен экземпляр (или ссылка на экземпляр) FormB, чтобы иметь возможность вызывать этот метод. Пока вы находитесь в FormA, у вас есть способ добраться до экземпляра FormA, но затем вам нужен способ добраться до FormB. Вы можете либо создать новый экземпляр FormB (следовательно, new B() работает), либо вы можете использовать другой класс, который управляет ссылками на все ваши формы или что-то подобное.   -  person dash    schedule 14.01.2012
comment
Это характерно для класса Form в VB.NET, совместимости с VB6. Разучиться этому всегда сложно. Вам просто нужно напомнить себе, что вы не можете передать имя типа, когда нужен объект.   -  person Hans Passant    schedule 14.01.2012
comment
@HansPassant Спасибо за информацию, я не знал, что Form так работает в VB.Net. Я предположил, что это больше не будет работать, и вместо этого использовал Меня ;-)   -  person dash    schedule 14.01.2012
comment
Ваш С# также является статическим методом (общим в VB.NET), которого нет в исходном VB.NET.   -  person Oded    schedule 14.01.2012


Ответы (3)


FormA и FormB — это классы в VB, экземпляры которых можно создавать так же, как в C#.

Однако Microsoft добавила поддержку автоматических экземпляров форм по умолчанию в VB.Net в VS2005, чтобы помочь разработчикам, переходящим с VB classic, которых смущала необходимость создавать экземпляры форм и управлять ими.

Однако это НЕ считается лучшей практикой программирования, поскольку может привести к различным проблемам, таким как невозможность доступа к форме из фонового потока и невозможность создания нескольких экземпляров формы.

Как только вы поймете ООП и создание экземпляров классов, у вас не будет абсолютно никаких причин использовать экземпляры по умолчанию.

На самом деле вы можете отключить использование экземпляров форм по умолчанию, либо создав Sub New в форме, объявленной Friend (чтобы ее можно было создать в другом месте проекта):

Friend Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

End Sub

или изменив Public Sub New, включив в него параметры:

Public Sub New(SomeValue As String)

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

End Sub

В любом случае любые ссылки на экземпляр формы по умолчанию приведут к следующим двум ошибкам времени компиляции, где бы ни упоминался экземпляр по умолчанию:

«Form1» является типом «WindowsApplication1» и не может использоваться в качестве выражения.

Для ссылки на член, не являющийся общим, требуется ссылка на объект.

Сказав все это о том, как ваше текущее приложение работает в VB.Net, конкретный ответ на ваш вопрос о C# заключается в том, что вам всегда нужно создавать новые экземпляры форм в C#.

Например:

AddForm(new formA(), new formB());
person competent_tech    schedule 14.01.2012

В: Я просто хочу знать, что в vb.net мы можем передавать исходный объект в качестве аргумента, не создавая его экземпляра.

A: То, что вы ищете, называется "передача по ссылке".

Вот несколько хороших примеров:

http://www.java2s.com/Code/VB/Language-Basics/ObjectparameterpassedbyValueandbyReference.htm

Вот документация Microsoft:

http://msdn.microsoft.com/en-us/library/ddck1z30.aspx

person paulsm4    schedule 14.01.2012
comment
Я не думаю, что это имеет какое-либо отношение к вопросу. - person Cody Gray; 14.01.2012

Я не уверен, но я почти уверен, что VB делает такое «псевдо-объектно-ориентированное программирование», где formA и formB являются объектами, а не классами. В вашей ситуации вы не создаете объекты в VB, вы просто манипулируете объектами formA и formB.

При переходе на C# вы имеете дело с объектами и классами. Ваш класс — «formA», но это просто структура для объектов типа «formA», которые вы будете создавать как объекты. Эта статья должна объяснять это еще немного.

person jrbalsano    schedule 14.01.2012
comment
Это только относится к классу Form для обратной совместимости с кодом VB 6. И вы, конечно же, можете использовать класс Form как обычно, поэтому лучше всего вообще не делать этого, даже в VB.NET. - person Cody Gray; 14.01.2012