在使用C#中返回用于使用的变量
我正在使用using语句中的using语句返回我正在创建的变量(听起来很有趣):
public DataTable foo () { using (DataTable properties = new DataTable()) { // do something return properties; } }
这将Dispose属性变量??
这样做后仍然得到这个警告:
警告34 CA2000:Microsoft.Reliability:在方法’test.test’中,在对所有引用超出范围之前,在对象’properties’上调用System.IDisposable.Dispose。
有任何想法吗?
谢谢
如果要返回它,则无法将其包装在using
语句中,因为一旦离开大括号,它就会超出范围并被处理掉。
你必须像这样实例化它:
public DataTable Foo() { DataTable properties = new DataTable(); return properties; }
稍后再调用Dispose()
。
是的,它将处置它 – 然后返回它。 这几乎总是一件坏事。
实际上对于DataTable
, Dispose
几乎从不做任何事情(例外情况是如果它在某处,IIRC),但它仍然是一个坏主意。 通常,您应该将处置的对象视为无法使用。
据说,这是创建一次性对象的工厂方法的模式。 但是,我仍然看到Code Analysis也抱怨这个:
Wrapper tempWrapper = null; Wrapper wrapper = null; try { tempWrapper = new Wrapper(callback); Initialize(tempWrapper); wrapper = tempWrapper; tempWrapper = null; } finally { if (tempWrapper != null) tempWrapper.Dispose(); } return wrapper;
这应该保证如果初始化失败,则对象被正确处理,但是如果一切都成功,则从该方法返回一个未曝光的实例。
MSDN文章: CA2000:在丢失范围之前处置对象 。
使用块的要点是为值/对象创建一个人工范围。 使用块完成后,将清除对象,因为不再需要它。 如果你真的想要返回你正在创建的对象,那么你不想使用它。
这将工作得很好。
public DataTable foo () { DataTable properties = new DataTable(); // do something return properties; }
使用using关键字的代码扩展为:
{ DataTable properties = new DataTable(); try { //do something return properties; } finally { if(properties != null) { ((IDisposable)properties).Dispose(); } } }
您的变量正在按照使用方式的性质进行处理。 如果您希望能够返回属性,请不要将其包装在using块中。
其他响应是正确的:只要退出使用块,就会丢弃对象。 使用块非常适合确保对象及时处理,因此如果您不想依赖函数的使用者来记住稍后处理该对象,您可以尝试这样的事情:
public void UsingDataContext (Action action) { using (DataContext ctx = new DataContext()) { action(ctx) } }
这样你可以这样说:
var user = GetNewUserInfo(); UsingDataContext(c => c.UserSet.Add(user));