C# 中的最佳实践:调用者或被调用者应该创建对象吗?
Best practice in C#: Should caller or callee create object?
尽管我的问题与 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
}
所以,回顾一下评论中写的内容(稍微改写一下):
DataTable 的使用就其本身而言可能不是最佳实践。使用 DataTables 的主要好处 use-case 是在设计时数据库模式未知的情况下。 (马克·格拉维尔 comment)
将引用类型传递给方法只是为了取回它是 return 值是没有意义的。对参数状态所做的任何更改都会反映到调用方法中,因为它是引用类型。 (我的comment)
如果该方法对 DataTable 的唯一用途是填充它并 return 它,则允许用户选择使用 DataTable 调用它不是明智的使用 - 因此具有方法接受数据 table 作为参数只是为潜在的混乱和错误打开了一扇门。 (埃里克·利珀特 comment)
该方法的目的是创建和return一个DataTable。该方法的合理行为是实例化 DataTable。更一般的经验法则:调用方法不需要为实例化被调用方法的 return 值而烦恼。 (Mikkel K. 的 comment)
关于配置DataTable/DataSet的次要点:
- 根据经验 - 任何实现
IDisposable
接口的 class 实例都应该被释放。虽然 DataTable 和 DataSet 确实不使用任何 non-managed 资源,并且 therefor doesn't actually need to be disposed, that is an implementation detail. The fact that some type implements the IDisposable
interface is the only thing you need to consider when asking if it should be disposed. One of the fundamental principles of object oriented programming is called Encapsulation. The main point of encapsulation that's related to this issue is that you should not be bothered with the implementation of the type you are dealing with, only with it's public interface. Another way to look at it is "Program to an 'interface', not an 'implementation'." (from Design Patterns: Elements of Reusable Object-Oriented Software)
(Jesse C. Slicer 的 comment and My second comment)
尽管我的问题与 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
}
所以,回顾一下评论中写的内容(稍微改写一下):
DataTable 的使用就其本身而言可能不是最佳实践。使用 DataTables 的主要好处 use-case 是在设计时数据库模式未知的情况下。 (马克·格拉维尔 comment)
将引用类型传递给方法只是为了取回它是 return 值是没有意义的。对参数状态所做的任何更改都会反映到调用方法中,因为它是引用类型。 (我的comment)
如果该方法对 DataTable 的唯一用途是填充它并 return 它,则允许用户选择使用 DataTable 调用它不是明智的使用 - 因此具有方法接受数据 table 作为参数只是为潜在的混乱和错误打开了一扇门。 (埃里克·利珀特 comment)
该方法的目的是创建和return一个DataTable。该方法的合理行为是实例化 DataTable。更一般的经验法则:调用方法不需要为实例化被调用方法的 return 值而烦恼。 (Mikkel K. 的 comment)
关于配置DataTable/DataSet的次要点:
- 根据经验 - 任何实现
IDisposable
接口的 class 实例都应该被释放。虽然 DataTable 和 DataSet 确实不使用任何 non-managed 资源,并且 therefor doesn't actually need to be disposed, that is an implementation detail. The fact that some type implements theIDisposable
interface is the only thing you need to consider when asking if it should be disposed. One of the fundamental principles of object oriented programming is called Encapsulation. The main point of encapsulation that's related to this issue is that you should not be bothered with the implementation of the type you are dealing with, only with it's public interface. Another way to look at it is "Program to an 'interface', not an 'implementation'." (from Design Patterns: Elements of Reusable Object-Oriented Software) (Jesse C. Slicer 的 comment and My second comment)