繁体   English   中英

C#反射-根据可用参数选择构造函数重载

[英]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
}

我已经写了一个控制台应用程序,正在写入数据库。 当执行应用程序时,用户提供一些命令行开关。

其中一些开关如下(还有一些与程序操作有关的开关,我在这里未包括在内):

  • / s:数据库服务器名称
  • / i:数据库实例名称
  • / d:数据库名称
  • / n:集成安全性(真或假)
  • / u:db用户名
  • / p:db密码

/ 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM