C#动态返回类型
本文关键字:返回类型 动态 | 更新日期: 2023-09-27 18:29:41
我已经解决了我的问题
public virtual T GenerateCommand()
{
Type typeParameterType = typeof(T);
if (typeParameterType == typeof(SqlCommand))
{
//SqlCommand
}
else if (typeParameterType == typeof(MySqlCommand))
{
//MySqlCommand
}
return new T()
{
};
}
我正在构建一个生成查询/命令的类,当在类的字段中定义数据库的类型时,该类能够生成各种DbCommands(MsSqlServer&MySql)。如何返回正确的类型?
我试过这个:
public virtual DbCommand GenerateCommand()
{
//.....
}
但我总是需要转换返回值:
MySqlCommand s = this.GenerateCommand() as MySqlCommand;
我也试过这个:
public virtual T GenerateCommand<T>()
{
//.....
}
但这不是我想要的,因为我不能创建DbCommand的实例,所以我不能什么都不返回。
是否有某种方式可以使T基于类中存储的类型?
编辑:泛型类的使用至少会引发两个异常:
if (T is MySqlCommand)
{
return new MySqlCommand();
}
else
{
return new SqlCommand();
}
"T"是一个"类型参数",但使用起来像一个"变量"
无法将类型"MySql.Data.MySqlClient.MySqlCommand"隐式转换为"T"
(T)MySqlCommand()
也不工作
编辑2:我能做这样的事吗?
public virtual T GenerateCommand(SqlDatabaseKind dbKind)
{
T = (dbKind == SqlDatabaseKind.MicrosoftSqlServer) ? SqlCommand :
MySqlCommand;
}
您可以拥有泛型类。听起来这更像是你想要的。然后,您可以将创建类的类型返回为:
public class MyDatabaseClass<T> where T : DbCommand
{
public virtual T GenerateCommand()
{
//.....
}
}
我使用了一个通用约束来确保T也是DbCommand类型。
您将"GenerateCommand()"设为void,并带有两个重载:一个接收"out MySqlCommand",另一个接收一个"out SqlCommand",并在函数中更改。
void GenerateCommand(out MySqlCommand com)
{
.
.
.
}
void GenerateCommand(out SqlCommand com)
{
.
.
.
}
out:http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.71).aspx
如果你想在数据库类型之间移动,那么你的代码应该依赖于抽象(DbCommand、DbConnection、DbParameter等),而不是具体的实现(SqlConnection、SqlCommand)。否则,当添加新的数据库提供程序时,您将不得不更改所有与数据库相关的代码。您将为每个提供程序复制所有与数据库相关的代码。
.Net已经有了用于创建所有这些与数据库相关的抽象的抽象工厂。它被称为DbProviderFactory。看起来这就是你想要实现的:
public virtual DbCommand CreateCommand()
public virtual DbConnection CreateConnection()
.Net具有此工厂的一些内置的特定于提供程序的实现(SqlClientFactory、OleDbFactory、OdbcFactory)。在这里你可以找到如何使用DbProviderFactory。在这里,您可以找到MySql的DbProviderFactory。