虽然我的问题类似于Freeing memory in caller or callee?,但这是针对C#的,更多的是关于谁应该创建一个对象而不是谁应该释放它。
哪种方法(或其他方法)代表最佳做法?我的直觉说方法1,因为谁知道谁实例化了这个对象呢?另一方面,DataTable不需要显式处理,那么谁在乎实例化呢?
方法#1
DataTable dataTable = dataAccessLayer._QueryDbGetAllTablesForDb(new DataTable());
.
//or
.
DataTable dataTable = new DataTable();
dataTable = dataAccessLayer._QueryDbGetAllTablesForDb(dataTable);
.
//then
DataTable _QueryDbGetAllTablesForDb(DataTable datatable);
{
.
sqlDataAdapter.Fill(dataTable);
.
return dataTable
}
方法#2
DataTable dataTable = dataAccessLayer._QueryDbGetAllTablesForDb();
.
//then
DataTable _QueryDbGetAllTablesForDb();
{
.
DataTable dataTable = new DataTable();
sqlDataAdapter.Fill(dataTable);
.
return dataTable
}
答案 0 :(得分:1)
所以,回顾一下评论中写的内容(稍作改写):
无论如何,使用DataTable本身可能不是最好的做法。使用DataTables的主要好用例是在设计时不知道数据库模式。 (Marc Gravell的comment)
没有必要将引用类型传递给方法,只是为了将它作为返回值返回。对参数的状态所做的任何更改都将反映到调用方法,因为它是引用类型。 (我的comment)
如果该方法仅使用DataTable来填充并返回它,则允许用户使用DataTable调用它的选项不是明智的用法 - 因此让该方法接受数据表作为参数只是为潜在的混乱和错误打开了一扇门。 (Eric Lippert的comment)
该方法的目的是创建并返回DataTable。该方法的合理行为是实例化DataTable。更一般的经验法则:调用方法不需要为实例化被调用方法的返回值而烦恼。 (Mikkel K.的comment)
关于处理DataTable / DataSet的次要问题:
IDisposable
接口的类的任何实例。虽然DataTable和DataSet确实不使用任何非托管资源,而therefor doesn't actually need to be disposed这是一个实现细节。某些类型实现IDisposable
接口的事实是在询问是否应该处理时唯一需要考虑的事情。面向对象编程的基本原则之一称为封装。与此问题相关的封装要点是,您不应该对您正在处理的类型的实现感到困扰,只能使用它的公共接口。查看它的另一种方法是"Program to an 'interface', not an 'implementation'."(来自Design Patterns: Elements of Reusable Object-Oriented Software)
(Jesse C. Slicer的comment和我的第二个comment)