我正在寻找一种优雅的解决方案,用于在C++中实现C#using语句的等价物.理想情况下,结果语法应该易于使用和阅读.
C#使用语句详细信息在这里 - http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx
我不确定解决方案是使用函数指针与类上的析构函数,某种形式的巧妙模板编程甚至是元模板编程.基本上我不知道从哪里开始......
我注意到很多东西来回的一件事是将使用语句放在C#代码文件中 - 无论是在最外层还是在命名空间内.我理解using语句的位置会影响该文件中引用的范围,但我不明白的是,在大多数情况下,有人会想要在其命名空间中使用它们的using语句.
在几乎所有情况下,单个文件中只存在一个名称空间声明,因此使用using语句的范围似乎/(是?)无效.如果一个人在同一个文件中放置了多个类型和多个命名空间,那么使用语句进行范围化就很有意义了,但即使在具有一个命名空间的文件中,我仍然会看到很多这种情况.为什么?
using System;
namespace MyNamespace
{
using System.Text;
public class MyClass {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在整个项目中,看似不必要的一个例子是ASP.NET MVC源代码.
我理解"使用"的意思是保证调用对象的Dispose方法.但是如何处理"使用"语句中的异常呢?如果有异常,我需要在try catch中包装我的"using"语句.例如:
可以说在using参数中创建对象时会创建一个异常
try
{
// Exception in using parameter
using (SqlConnection connection = new SqlConnection("LippertTheLeopard"))
{
connection.Open();
}
}
catch (Exception ex)
{
}
Run Code Online (Sandbox Code Playgroud)
或使用范围内的异常
using (SqlConnection connection = new SqlConnection())
{
try
{
connection.Open();
}
catch (Exception ex)
{
}
}
Run Code Online (Sandbox Code Playgroud)
好像我已经需要使用try catch来处理异常,也许我应该只处理对象的处理.在这种情况下,"使用"声明似乎并没有帮助我.如何使用"using"语句正确处理异常?我错过了更好的方法吗?
SqlConnection connection2 = null;
try
{
connection2 = new SqlConnection("z");
connection2.Open();
}
catch (Exception ex)
{
}
finally
{
IDisposable disp = connection2 as IDisposable;
if (disp != null)
{
disp.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
"使用"关键字语法可能会更加含糖......
这肯定会很好: …
这是我过去多次问自己的一个问题,因为我使用语句5深度嵌套.
阅读文档并且没有提及关于在块内实例化的其他一次性用品的任何方式,我认为它对于SO档案来说是一个很好的Q.
考虑一下:
using (var conn = new SqlConnection())
{
var conn2 = new SqlConnection();
}
// is conn2 disposed?
Run Code Online (Sandbox Code Playgroud) 我正在使用using语句中的using语句返回我正在创建的变量(听起来很有趣):
public DataTable foo ()
{
using (DataTable properties = new DataTable())
{
// do something
return properties;
}
}
Run Code Online (Sandbox Code Playgroud)
这将Dispose属性变量??
这样做后我仍然得到这个警告:
警告34 CA2000:Microsoft.Reliability:在方法'test.test'中,在对所有对它的引用超出范围之前,对对象'properties'调用System.IDisposable.Dispose.
有任何想法吗?
谢谢
使用ReSharper移动/更新名称空间声明时,有没有办法阻止ReSharper删除未使用的Using语句?
换句话说,如果我有一个类,如:
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Foo.Bar
{
class MyClass
{
List<string> Names { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用ReSharper将它移动到Foo.Bar.Utilities命名空间,Resharper将删除所有未使用的Using语句,并留下我:
using System.Collections.Generic;
namespace Foo.Bar.Utilities
{
class MyClass
{
List<string> Names { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不希望ReSharper在移动命名空间声明时触摸我的Using语句.我希望结果如下:
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Foo.Bar.Utilities
{
class MyClass
{
List<string> Names { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud) 有人可以向我解释为什么下面显示的代码在C#中有效并执行调用Console.WriteLine?
using (null)
{
Console.WriteLine ("something is here")
}
Run Code Online (Sandbox Code Playgroud)
它编译成(最后显示块).如您所见,编译器决定不执行该Dispose()方法并跳转到该endfinally指令.
IL_0013: ldnull
IL_0014: ceq
IL_0016: stloc.1
IL_0017: ldloc.1
IL_0018: brtrue.s IL_0021 // branches here and decide not to execute Dispose()
IL_001a: ldnull
IL_001b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0020: nop
IL_0021: endfinally
Run Code Online (Sandbox Code Playgroud)
但是,如果我运行以下代码,它将失败a NullReferenceException(预期):
((IDisposable)null).Dispose();
IL_0023: ldnull
IL_0024: callvirt instance void [mscorlib]System.IDisposable::Dispose()
Run Code Online (Sandbox Code Playgroud)
为什么第一个版本编译?为什么编译器决定不执行Dispose()?是否有任何其他情况下,当编译器可以决定不叫Dispose()的using块?
这个问题更多的是做某事的正确方法......
问题是......在一个using块和一个块之间是否存在正确的嵌套顺序try/catch?
是否可以将整个using语句嵌套在a中try/catch并保持using块的好处?(或者异常会导致using语句的结束部分被抛出窗口)
或者,您是否应该try/catch在using语句内部嵌套,并且只包含进行数据库访问的语句?
是...
try {
using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
violationList = ( from a in db.DriverTrafficViolationDetails
where a.DriverTrafficViolation.DriverApplicationId == DriverAppId
orderby a.DateOfOccurance descending
select a ).ToList<DriverTrafficViolationDetail>();
GeneralViolation = ( from a in db.DriverTrafficViolations
where a.DriverApplicationId == DriverAppId
select a ).FirstOrDefault();
}
} catch { }
Run Code Online (Sandbox Code Playgroud)
少于/多于......
using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
try {
violationList = ( from …Run Code Online (Sandbox Code Playgroud) 我刚刚发现像C#一样,VB.NET也有using关键字.
到现在为止,我认为它没有它(愚蠢的我,我知道......)并做了这样的事情:
With New OleDbConnection(MyConnectionString)
' Do stuff
End With
Run Code Online (Sandbox Code Playgroud)
与使用这样的using语句相比,这有什么影响
Using cn as New OleDBConnection(MyConnectionString)
With cn
' Do stuff with cn
End With
End using
Run Code Online (Sandbox Code Playgroud)
更新:
我应该补充一点,我熟悉using语句的作用,因为它在退出构造时处理了对象.
但是,据我所知,With New ...构造将使对象在对象超出范围时将其标记为垃圾收集.
所以我的问题是,唯一的区别在于using我将立即释放内存,而对于With构造,只要GC感觉它就会被释放吗?或者我错过了更大的东西?
是否有最佳实践意义?我应该去重写所有的代码我用With New MyDisposableObject() ... End With的Using o as New MyDisposableObject()?
GCC 4.8.1接受
template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass<T>::Baseclass;
};
Run Code Online (Sandbox Code Playgroud)
但MSVC没有.另一方面,MSVC接受
template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass::Baseclass;
};
Run Code Online (Sandbox Code Playgroud)
但海湾合作委员会没有.然后我在这个问题中看到了另一种声明:c ++ 11继承模板构造函数
template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass::Baseclass<T>;
};
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会表示,MSVC警告称"过时的申报风格"
prog.cpp:8:24: error: ‘template<class T> class Baseclass’ used without template parameters
using typename Baseclass::Baseclass<T>;
Run Code Online (Sandbox Code Playgroud)
我认为第一个例子是标准的符合语法.直观地说,它对我来说是正确的.
什么是c ++ 11标准符合语法?
using-statement ×10
c# ×8
c++ ×2
dispose ×2
idisposable ×2
scope ×2
using ×2
vb.net ×2
.net ×1
c++11 ×1
constructor ×1
namespaces ×1
resharper ×1
templates ×1
try-catch ×1