В C ++ / CLI вы должны объявлять ссылки на объекты с завершающим ^
, аналогично оператору *
для собственных указателей.Более того, методы для ссылок чаще всего вызываются с помощью оператора ->
.Попробуйте это:
public: static bool TcpSocketTest ()
{
try
{
System::Net::Sockets::TcpClient^ Client = gcnew System::Net::Sockets::TcpClient ("www.google.com", 80);
Client->Close ();
return true;
}
catch (System::Exception ^ex)
{
return false;
}
}
РЕДАКТИРОВАТЬ: Как правильно указывает Ганс Пассант, есть еще одна проблема с этим кодом, которая не является синтаксической.Поскольку TcpClient
реализует IDisposable
, а вызов Close()
находится в блоке try
, ссылка на объект никогда не удаляется в случае исключения.Поэтому вызов Close()
должен находиться за пределами блока try
.
Однако C ++ / CLI предлагает гораздо лучший способ решения этой проблемы, который называется «семантика стека».Это эквивалентно утверждению C # using
.Он используется так:
public: static bool TcpSocketTest ()
{
try
{
System::Net::Sockets::TcpClient Client (L"www.google.com", 80);
// Dispose() or Close() not needed anymore
return true;
}
catch (System::Exception ^ex)
{
return false;
}
}
Так что ссылка TcpClient
объявлена как локальная переменная.Но на самом деле он будет создан в куче, и как только переменная Client
выйдет из области видимости, Client.Dispose ()
будет вызван автоматически.Следовательно, вызов Close()
вообще не нужен, и объект удаляется должным образом, независимо от того, выбрасывается ли исключение или метод завершается нормально.
Спасибо Хансу Пассанту за указание на это.Семантика стека для IDispose
является хорошей практикой в C ++ / CLI.
Обратите внимание, что я изменил литерал String в конструкторе на L"..."
.Это также хорошая практика, потому что пропуск «L» приведет к проблемам, как только символы Unicode будут выходить за пределы 8-битного диапазона.