有一个接口IDbData,其中定义了要实现成员:
int ExecuteNonQuery(string sqlStr, CommandType commandType, params DbParameter[] parameters);
OleDbData实现了上述接口,其中实现了上面的方法:
int ExecuteNonQuery(string sqlStr, CommandType commandType, params OleDbParameter[] parameters);
编译出错:“OleDbData”不实现接口成员“IDbData.FillDataTable(string, System.Data.CommandType, params System.Data.Common.DbParameter[])”
假如把接口中那个最后一个参数类型改成OleDbParameter[]当然可以,但本人另外一个类MySqlData中对应的方法就不能通过编译了。也就是说接口IDbData中方法最后一个参数声明为params DbParameter[] parameters,那么实现该接口的SqlData、MySqlData、OleDbData……里对应方法的最后一个参数该怎么声明?(除了声明为DbParameter[]可以外,还有什么办法?)。
解决方案
25
写了点测试代码:
public interface ITest<T> where T:DbParameter { int ExecuteNonQuery(string sqlStr, CommandType commandType, params T[] parameters); } class TestSQLParameter : ITest<SqlParameter> { public int ExecuteNonQuery(string sqlStr, CommandType commandType, params SqlParameter[] parameters) { Console.Write("enter TestSQLParameter.ExecuteNonQuery. Count: " + parameters.Count()); return 0; } }
调用
TestSQLParameter test = new TestSQLParameter();
test.ExecuteNonQuery(“111”, CommandType.StoredProcedure, new SqlParameter(“1”, 1), new SqlParameter(“2”, 2),
new SqlParameter(“3”, 3));
5
现阶段,只能通过emit产生代理类解决这个问题了。
20
把设计的理念再重新说明白一点,就是:
面向对象的系统设计,不是说“一味地把具体实现推迟到子类中”。推迟是个不好的习惯,是滥用继承的表现。一个好的系统,它是在父类程序中直接调用通用的 ExecuteNonQuery 方法,在父类中就完成了核心的程序流程。
只有极个别的“获取局部参数”操作才在子类中重构。
假如你设计的程序总是把核心处理推迟到子类中处理,那么肯定会遇到这种尴尬,那么需要重新理解一下你对面向对象编程的思路,可能是有误区的。
面向对象的系统设计,不是说“一味地把具体实现推迟到子类中”。推迟是个不好的习惯,是滥用继承的表现。一个好的系统,它是在父类程序中直接调用通用的 ExecuteNonQuery 方法,在父类中就完成了核心的程序流程。
只有极个别的“获取局部参数”操作才在子类中重构。
假如你设计的程序总是把核心处理推迟到子类中处理,那么肯定会遇到这种尴尬,那么需要重新理解一下你对面向对象编程的思路,可能是有误区的。