根据c#中使用的构造函数显示或隐藏类中的函数



考虑以下类

public class DataManager
{
  private SqlConnection cn;
  public SqlCommand cmd;
  public DataManager(bool initializeCmd=true)
  {
    string conString="server=192.168.1.20;User Id=sa;pwd=123;Persist Security Info=True; database=testDB";       
    cn = new SqlConnection(conString);
    if (initializeCmd)
      cmd = new SqlCommand();            
  }
  public void OpenDbConnection()
  {
    if (cn.State == ConnectionState.Closed)
      cn.Open();            
  }       
  public void CloseDbConnection()
  {
    if (cn.State == ConnectionState.Open)
      cn.Close();
  }
  public bool Update_Database()
  {
    cmd.Connection = cn;
    OpenDbConnection();
    int n=cmd.ExecuteNonQuery();
    CloseDbConnection();
    if(n>0) { return true; }
    else { return false; }
  }
  public bool Update_Database(string cmdTxt, bool isProcedure)
  {   
    cmd = new SqlCommand(cmdTxt, cn);
    if (isProcedure)
      cmd.CommandType = CommandType.StoredProcedure;
    else
      cmd.CommandType = CommandType.Text;
    OpenDbConnection();
    int n=cmd.ExecuteNonQuery();
    CloseDbConnection();
    if(n>0) { return true; }
    else { return false; }
  }            
}

现在考虑第二类

public class staff
{
  DataManager dm;
  public bool resetPwd(string code)
    {
        dm = new DataManager(false);
        string query= "UPDATE Staff WHERE pwd='123' WHERE code="+code;            
        return dm.Update_Database(query,false);
    }
    public bool changePwd(string code,string pwd)
    {
        dm = new DataManager();
        dm.cmd.CommandText = "UPDATE Staff WHERE pwd=@pwd WHERE code=@code";
        dm.cmd.Parameters.Clear();
        dm.cmd.Parameters.AddWithValue("@code", code);
        dm.cmd.Parameters.AddWithValue("@code", code);
        return dm.Update_Database();
    }
}

DataManager类是处理数据库操作的常用类。现在我的问题是是否有办法阻止我使用

Update_Database() 
调用 时的

函数

dm = new DataManager(false) 

代替

dm = new DataManager() 

from staff class。因为如果我使用dm = new DataManager(false),它将抛出一个错误,因为sql命令对象没有初始化。

没有什么可以阻止别人初始化dm = new DataManager(true)。如果需要的数据库更新不可用,则将其从DataManager移出。创建另一个DatabaseUpdater类,负责数据库更新操作。注意:Update方法的名称是误导-他们应该执行UPDATE查询,但我可以传递DELETE查询文本,并执行它。

顺便说一句,DataManager的有用性是有争议的。ADO。NET使用连接池来最小化打开连接的成本。另外,硬编码连接字符串也不是一个好主意。使用配置文件的connectionStrings部分来提供它们。

我建议你看一下Dapper库,它会使你的代码看起来像这样:

public bool ChangePassword(string code, string pwd)
{
    using(DbConnection conn = GetConnection())
    {
        string sql = "UPDATE Staff SET pwd=@pwd WHERE code=@code";
        int updatedRowsCount = conn.Query<int>(sql, new { code, pwd }).First();
        return updatedRowsCount == 1;
    }
}

连接将自动打开和关闭。命令将被创建,所有参数将被添加到命令中。我还没有提供GetConnection实现-它负责读取连接字符串并返回新连接。

最后一个建议-避免接受布尔参数的方法。这种参数很容易混淆。DataManager(true)是什么意思?与DataManager(false)有何不同?

不能自动显示和隐藏功能。一旦你的代码编译好了,就不能动态修改了。

你能做的不是那么"整洁"的是抛出一个异常或者根本不运行代码。这是非常糟糕的界面设计,因为它创建的行为不容易理解。

如果你真的想,你可以设置你的DataManager接收数据库连接字符串:

 string connectionString = "...";
 DataManager dm = new DataManager(connectionString);

如果实现者不知道连接字符串,他们将无法打开连接。

这不是"最佳设计",但它回答了你的问题。

一个更好的解决方案可能只是暴露一个bool属性,如果命令是可用的。这样,如果允许使用该方法,消费者可以先进行测试。如果他们仍然想调用它,那么抛出一个异常。

重要的是他们有办法自己测试。

。NET 4.5可能是4,引入了可以在运行时改变方法的动态类对象。我不想在我的代码中这样使用它,但它确实存在。

为什么不在执行Update_Database()之前检查initializeCmd == true(从函数内部)?如果它的值是false(只是返回),则执行NOP。您可以将SqlCommand初始化为默认值,这样调用该方法就不会产生任何副作用。或者在执行之前检查命令是否为空。您还可以对不同的专门化类行为使用继承。

编辑:如果你不喜欢#warning, . net的代码契约库可以帮助你根据类的使用方式显示警告。

代码契约是任何。net程序中用于指定代码行为的静态库方法。

使用库使您能够使用静态检查来检查契约违反。(如果你真的认为这是必要的!)

最新更新