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

时间:2014-08-09 10:18:28

标签: 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() 

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

4 个答案:

答案 0 :(得分:2)

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

DataManager的BTW有用性是有争议的。 ADO.NET使用connection pooling来最小化打开连接的成本。硬编码连接字符串也不是一个好主意。使用配置文件的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)的区别如何?

答案 1 :(得分:1)

您无法自动“显示和隐藏”功能。一旦您的代码编译,就无法动态更改。

你可以做什么,哪个不那么“整洁”要么抛出异常,要么根本不运行代码。这是非常糟糕的界面设计,因为它会产生无法轻易理解的行为。

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

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

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

这不是“最佳设计”,但它可以回答您的问题。

答案 2 :(得分:0)

更好的解决方案可能只是在命令可用时公开bool属性。这样,消费者可以首先测试该方法是否被允许。如果他们仍想调用它,则抛出异常。

重要的是,他们有能力为自己进行测试。

.NET 4.5可能4,介绍了动态类对象,它可以在运行时更改方法。我不想在我的代码中以这种方式使用它,但它就在那里。

答案 3 :(得分:0)

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

编辑: 如果您不喜欢#warning,图书馆Code Contracts for .NET可以帮助您显示警告,具体取决于课程的使用情况。

  

代码约定是从任何.NET程序使用的静态库方法,用于指定代码的行为。

使用该库可以使用静态检查来检查合同违规。 (如果你真的认为这是必要的!)