[英]C# reflection - choosing constructor overload based on available parameters
我已经编写了一个通用数据库类,可以调用它来执行通用数据库(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
}
我已经写了一个控制台应用程序,正在写入数据库。 当执行应用程序时,用户提供一些命令行开关。
其中一些开关如下(还有一些与程序操作有关的开关,我在这里未包括在内):
/ 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语句实现对构造函数的选择,该语句执行上述逻辑中的测试,但是我只是想知道是否有一种更优雅的方法去做这个?
我建议一种更简单的方法。 使用一个单独的构造函数来适当地设置您的成员:
public MyClass(params string[] switches)
{
if(switches.Contains("/i") this.i = ...
...
}
您还可以创建一个包含所有选项为true
的简单列表。
要调用此构造函数,只需使用以下命令:
var instance = Activator.CreateInstance(myType, suppliedParameters);
如果要使用反射,请使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.