进入一个有趣的问题,我想知道是否有人可以帮助解释。我试过在互联网上搜索,似乎无法找到这个问题的答案。虽然我们有一个解决方案,但其他人可能遇到同样的问题,因为它是随机的,所以很难追查。
当计算机连接到客户公司网络时,我们有一个随机失败的应用程序(网络上没有大量信息)。当我们将计算机带到我们的环境中时,它运行良好。失败是相当随机的,但在从C#调用到非托管第三方供应商DLL期间,我发现最好。我所拥有的跟踪之一(系统事件日志中只有几个故障提供了跟踪)指示在调用非托管DLL的参数编组期间RtlMoveMemory函数中的ntdll.dll失败。
对非托管功能的调用是:
ThirdParty.CxxxAutomationWrapper clientDLL = new ThirdParty.CxxxAutomationWrapper () ;
object Parameter1 ;
:
string theValue = "abcde" ;
Parameter1 = theValue ;
:
if ( Parameter1 is string )
{
int returnCode = clientDLL.function ( Parameter1 as string ) ;
}
呼叫定期在客户计算机上失败,但在Visual Studio(2010)中运行时始终有效。 Parameter1的值已正确设置(永不为空)。
因为我将呼叫改为:
String parameter1String = Parameter1.ToString() ;
int returnCode = clientDLL.function ( parameter1String ) ;
一切都运转良好。 Parameter1的值非常受控制,在执行此代码之前不为null。
被调用的接口(clientDLL.function)定义为:
HRESULT function ( [in] BSTR parameter,
[out, retval] long *ret);
由于我对c#中'as'语句的理解有限,我不明白为什么第一个版本失败了。任何人都可以帮助解释为什么在使用指定为“as string”的参数调用时失败?
答案 0 :(得分:5)
因为obj as string
和obj.ToString()
不一样。第一个是尝试强制转换(类似于(string)obj
,但在失败时返回null
),而秒是一个方法调用,返回对象的字符串表示。
实际上,您可以获取任何对象的字符串表示形式,无论它是否与字符串作为类型兼容,但如果它们不兼容,则转换将失败。
简单示例:
object obj = new object(); // simple object
Console.WriteLine(obj.ToString()); // prints System.Object
Console.WriteLine((obj as string) == null); // True: obj is not a string!
答案 1 :(得分:2)
Parameter1.ToString()
会将任何.NET对象呈现为字符串(即System.String
的实例)。如果Parameter1 as string
为空,或者null
不是Parameter1
的实例,System.String
将返回null
。如果它是一个包装字符串而不是实际 的字符串的类,那么最终会得到一个System.String
。
当然,两种情况都不适用。如果您的null
实例为Parameter1 as string
,那么null
将正确返回Parameter1.ToString()
,而NullReferenceException
会抛出Convert.ToString(Parameter1)
。< / p>
安全的方法是:{{1}}。
答案 2 :(得分:0)
Parameter1 as string
可以被认为是
string foo
try
{
foo = (string)Parameter1;
}
catch
{
foo = null;
}
其中.ToString()
是
string foo = Parameter1.ToString();
参数1不能直接转换为字符串的事实是它失败的共鸣。