我遇到了一些问题,我根本无法找到一个好的解决办法。
我希望有这3个重载:
public IList<T> GetList<T>(string query) where T: string
public IList<T> GetList<T>(string query) where T: SomeClass
public IList<T> GetList<T>(string query) where T: struct
显然第一个约束甚至不会单独编译,所以这是我的第一个问题。 (我意识到我可以让它成为IList,但我想要三个相同的语法)
无论如何,所有这些的原因是,这些方法是围绕对数据库执行SQL查询的包装器的一部分 - 我希望能够将结果作为字符串列表返回(以防有人选择varchar列),一个valuetypes列表(int,float,whatever)或类列表(这些类代表表,因此包含多个列)
我希望这部分有点可以理解: - )
无论如何,我的大问题显然是我无法进行这些重载,因为它们使用相同的名称和参数列表。
此外,我无法将它们合并到同一个方法中,因为我需要在该实现中调用SomeClass上的方法,所以除非我想做一些重型类型转换,或者更糟糕的是反射 - 我需要这个约束。
我意识到我正在努力做的事情是不可能的,所以我正在寻找的是一种很好的方法,它会模仿我的意图。
如果其中一些有点不清楚,请随时问: - )
编辑:
这是我当前的“where T:SomeClass”版本的代码。我正在尝试将字符串/值类型的支持添加到当前代码中,所以也许我最初的方法是完全错误的 - 基本上欢迎任何想法: - )
public IList<TValue> GetList<TValue>(string query) where TValue : DbTable, new()
{
DataSet dataSet = GetDataSet(query);
IList<TValue> result = new List<TValue>();
if (dataSet.Tables.Count > 0)
{
foreach (DataRow row in dataSet.Tables[0].Rows)
{
TValue col = new TValue();
col.Fill(row);
result.Add(col);
}
}
return result;
}
正如您所看到的,我需要确切的DbTable类型才能获得正确的构造函数。 Fill是DbTable的抽象方法(它是一个抽象类)。
答案 0 :(得分:12)
正如你所说;对此没有任何好的选择。您可能会考虑不同的名称(而不是重载) - GetStringList
等。
但是,我想知道放弃约束是否更简单。使用“as”的单一类型检查并不是完全“重型”的类型转换,它可能会节省很多痛苦。
答案 1 :(得分:3)
这是怎么回事?
public IList<T> GetList<T>(string query) where T : new()
{
// whatever you need to distinguish, this is a guess:
if (typeof(T).IsPrimitiveValue)
{
GetPrimitiveList<T>(query);
}
else if (typeof(T) == typeof(string))
{
GetStringList<T>(query);
}
else
{
GetEntityList<T>(query);
}
}
private IList<T> GetStringList<T>(string query)
private IList<T> GetPrimitiveList<T>(string query)
private IList<T> GetEntityList<T>(string query)