这是代码
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;
}
}
我正在尝试检查网络连接,并在Internet上找到了此代码,并对其进行了一些更改以使其与我的项目兼容,但是它说
no suitable user-defined conversion from "System::Net::Sockets::TcpClient ^" to "System::Net::Sockets::TcpClient" exists Project1 33
我对此非常陌生,所以我不知道自己在做什么。
答案 0 :(得分:1)
在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;
}
}
编辑:正如汉斯·帕桑特(Hans Passant)正确指出的那样,此代码还有另一个问题,这不是语法问题。由于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()
调用都是完全不必要的,并且对象已正确处理。
感谢Hans Passant指出了这一点。 IDispose
的堆栈语义是C ++ / CLI的良好做法。
请注意,我将构造函数中的String文字更改为L"..."
。这也是一个好习惯,因为一旦使用8位范围以外的Unicode字符,省略“ L”将导致问题。