我编写了一个通用数据库类,可以调用它来执行通用数据库 (CRUD) 操作,从而避免在多个解决方案中重写 ADO.NET 代码。为了使其灵活,根据不同的数据库身份验证类型和实例类型等,有许多构造函数重载。类如下:
class Database
{
// default instance with Windows authentication
// constructor 1
public Database(string server, string database, bool persistSecurityInfo)
{
_server = server;
_database = database;
_persistSecurityInfo = persistSecurityInfo;
_integratedSecurity = "True";
_connectionString = "Data Source=" + server + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";Integrated Security=True";
}
// named instance using Windows authentication
// constructor 2
public Database(string server, string instance, string database, bool persistSecurityInfo) : this(server, database, persistSecurityInfo)
{
_instance = instance;
_integratedSecurity = "True";
_connectionString = "Data Source=" + server + "\\" + instance + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";Integrated Security=True";
}
// default instance with SQL authentication
// constructor 3
public Database(string server, string database, bool persistSecurityInfo, string userName, string password) : this(server, database, persistSecurityInfo)
{
_userName = userName;
_password = password;
_integratedSecurity = "False";
_connectionString = "Data Source=" + server + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";User ID=" + userName + ";Password=" + password;
}
// named instance with SQL authentication
// constructor 4
public Database(string server, string instance, string database, bool persistSecurityInfo, string userName, string password) : this(server, database, persistSecurityInfo, userName, password)
{
_instance = instance;
_integratedSecurity = "False";
_connectionString = "Data Source=" + server + "\\" + instance + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";User ID=" + userName + ";Password=" + password;
}
private string _server;
private string _instance;
private string _database;
private bool _persistSecurityInfo;
private string _userName;
private string _password;
private string _integratedSecurity;
private string _connectionString;
private string _query;
//CRUD Methods here
}
我编写了一个正在写入数据库的控制台应用程序。当应用程序执行时,用户提供一些命令行开关。
部分开关如下(还有其他与程序运行有关的开关,我没有在这里包括):
- /s : 数据库服务器名称
- /i : 数据库实例名
- /d : 数据库名
- /n:集成安全性(对或错)
- /u : 数据库用户名
- /p : 数据库密码
/i、/u 和/p 是可选的(例如,如果未提供实例名称,程序假定它连接到/s 上的默认实例)
因此,我需要程序在运行时根据提供的参数决定调用哪个构造函数。
这里是伪例子
Class Program
{
static void Main(string[] args)
{
foreach (string arg in args[])
{
//code to work out which parameters have been provided here and adds them to array. Also other code which checks integrity such as ensuring there is no username without a password and vice versa etc.
string[] suppliedParameters;
//if there is a /i , /u , /p parameters, use constructor 4
//if there is a /u and /p but no /i, use constructor 3
//if there is an /i but no /u or /n use constructor 2
//if there is no /i, /u or /n, use constructor 1
}
}
}
我知道我可以使用反射来执行相关的构造函数,并且我可以在 Main 方法中使用 switch 语句来实现对构造函数的选择,该方法在上面的逻辑中执行测试,但我只是想知道是否有可能更优雅的方式来做到这一点?
最佳答案
如果您想使用反射,请使用Activator.CreateInstance 方法,该方法接受对象的类型和数组作为参数。它会根据数组中的项数和项类型自动调用所需的构造函数。
object[] arguments = //Create array based on input
DataBase db=(DataBase)Activator.CreateInstance(typeof(Database), arguments); // This will call matching constructor based on array passed
关于C# 反射 - 根据可用参数选择构造函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43518052/