从 'using' 语句中的函数返回资源实例是否与直接在 'using' 语句中实例化资源相同?
Is returning a resource instance from a function in a 'using' statement the same as instantiating the resource directly in the 'using' statement?
我正在尝试遵循此处定义的 'using' 的最佳做法:
You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use the object outside the using block, you risk causing an exception to be thrown. For this reason, it is generally better to instantiate the object in the using statement and limit its scope to the using block.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
鉴于该规则,我认为这是错误的:
private PrincipalContext GetDomainContext(
out bool bFailedBecauseDomainServerIsInaccessible
)
{
bFailedBecauseDomainServerIsInaccessible = false;
try
{
return new PrincipalContext(
ContextType.Domain,
null
);
}
catch (PrincipalServerDownException downEx)
{
bFailedBecauseDomainServerIsInaccessible = true;
}
catch (Exception ex)
{
}
return null;
}
//calling logic...
PrincipalContext ctxDomain = null;
bool bErrorHittingDomainServer = false;
ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
);
using (ctxDomain)
{
//do stuff and automatically dispose when finished
}
问题是,如果我在 'using' 语句中使用相同的 'GetDomainContext' 函数和 return PrincipalContext 是否仍然违反 Microsoft Doc 的最佳实践?
using (ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
该样式将符合 Microsoft 最佳实践,但您可以考虑不使用 out 参数。相反,请考虑使用异常来处理 "error hitting domain server" 问题。因此将使用包装在 try/catch 块中,并捕获 "ErrorHittingDomainServer" 异常并适当地处理它。
using 块是为了确定"that Disposeable stuff is disposed when it is no longer needed"。
在内部实现为(或接近于):
try{
ctxDomain = GetDomainContext(out bErrorHittingDomainServer);
//The other code inside the using block
}
finally{
if(ctxDomain != null){
ctxDomain.Dispose();
}
}
我对任何一次性物品的一般规则是:
创造。采用。处置。全部在同一段代码中,最好使用 using 块。
将任何可丢弃的东西分开创建和丢弃只会自找麻烦。抵制出于任何原因(包括性能)而这样做的诱惑,除非您实际工作的级别可以处理 Unamanged Resoruces 直接。大多数 Disposeable 类 都在那里,因此您只能间接处理未处理的东西。
你的最后一个块仍然违反了所提出的建议,因为在 using
语句之后变量仍然存在(即 在范围 中)。试图说明的一点是,使用您的代码,您可以这样做:
PrincipalContext ctxDomain = null;
using (ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
//This will throw a null reference exception at runtime
ctxDomain.DoStuff();
但是,如果您的代码是这样的:
using (PrincipalContext ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
//This line of code won't even compile because the variable is not in scope here
ctxDomain.DoStuff();
所以在第一个块中,您可以在 运行时 出现致命异常,但第二个块将永远不允许您首先进行编译。
我正在尝试遵循此处定义的 'using' 的最佳做法:
You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use the object outside the using block, you risk causing an exception to be thrown. For this reason, it is generally better to instantiate the object in the using statement and limit its scope to the using block.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
鉴于该规则,我认为这是错误的:
private PrincipalContext GetDomainContext(
out bool bFailedBecauseDomainServerIsInaccessible
)
{
bFailedBecauseDomainServerIsInaccessible = false;
try
{
return new PrincipalContext(
ContextType.Domain,
null
);
}
catch (PrincipalServerDownException downEx)
{
bFailedBecauseDomainServerIsInaccessible = true;
}
catch (Exception ex)
{
}
return null;
}
//calling logic...
PrincipalContext ctxDomain = null;
bool bErrorHittingDomainServer = false;
ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
);
using (ctxDomain)
{
//do stuff and automatically dispose when finished
}
问题是,如果我在 'using' 语句中使用相同的 'GetDomainContext' 函数和 return PrincipalContext 是否仍然违反 Microsoft Doc 的最佳实践?
using (ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
该样式将符合 Microsoft 最佳实践,但您可以考虑不使用 out 参数。相反,请考虑使用异常来处理 "error hitting domain server" 问题。因此将使用包装在 try/catch 块中,并捕获 "ErrorHittingDomainServer" 异常并适当地处理它。
using 块是为了确定"that Disposeable stuff is disposed when it is no longer needed"。
在内部实现为(或接近于):
try{
ctxDomain = GetDomainContext(out bErrorHittingDomainServer);
//The other code inside the using block
}
finally{
if(ctxDomain != null){
ctxDomain.Dispose();
}
}
我对任何一次性物品的一般规则是: 创造。采用。处置。全部在同一段代码中,最好使用 using 块。
将任何可丢弃的东西分开创建和丢弃只会自找麻烦。抵制出于任何原因(包括性能)而这样做的诱惑,除非您实际工作的级别可以处理 Unamanged Resoruces 直接。大多数 Disposeable 类 都在那里,因此您只能间接处理未处理的东西。
你的最后一个块仍然违反了所提出的建议,因为在 using
语句之后变量仍然存在(即 在范围 中)。试图说明的一点是,使用您的代码,您可以这样做:
PrincipalContext ctxDomain = null;
using (ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
//This will throw a null reference exception at runtime
ctxDomain.DoStuff();
但是,如果您的代码是这样的:
using (PrincipalContext ctxDomain = GetDomainContext(
out bErrorHittingDomainServer
))
{
//do stuff and automatically dispose when finished
}
//This line of code won't even compile because the variable is not in scope here
ctxDomain.DoStuff();
所以在第一个块中,您可以在 运行时 出现致命异常,但第二个块将永远不允许您首先进行编译。