我已将自己编码到一个角落,并希望您的帮助能够再次挖掘我。在正确的方向。在C#中创建通用接口的实例的方法
所以,我已经实现了一个次要的SQLite的包装,我想该解决方案是通用(我们不都是)。之后,我现在意识到这些类和接口的使用不是很直观,也不是通用的。
让我们从底部开始,向上工作。我创建了一个名为DataRow
的类,它用作我的表格行的基类。类DataRow
本身只有一个属性Id
(因为所有行都需要一个)。这导致了如下定义:class DataRow { public int Id { get; set; } }
使用这个DataRow
类,是每个表。对于数据库表,我创建了一个通用接口和一个通用基类。定义如下所示:
internal interface ITable<T>
where T : DataRow, new()
{
T Select(int id);
List<T> Select(List<int> ids);
int Insert(T t);
void Update(T t);
bool Delete(int id);
}
public class Table<T> : ITable<T>
where T : DataRow, new()
{
// Commented out to protect you from a minor case of serious brain damage.
}
此设置允许我创建简明的定义。事实上,他们往往是相当史诗般的,真的。骄傲地说。
public class Car : DataRow
{
public decimal ParkingTicketDebt { get; set; }
public DateTime WhenWifeWillAllowReplacement { get; set; }
public bool CanTransformIntoSomethingAwesome { get; set; }
}
public class Cars : Table<Car> {
// Yep, that's all. You can go home now, folks. There's nothing here. Nothing at all. Especially not a great treasure of gold. Whops... I mean... there's really not. Not that I'm aware of, anyway... I mean, there could be. Not that I wouldn't say if I had any information on this great trasure of gold that might exist. But I know nothing of such an item. I really don't, so you can stop thinking about this great treasure of gold. Since I don't know anything about it, the chance that it even exist is extremely low. Miniscule. I mean, you would probably not find anything, not even if you digged for, like, a really long time. Seven years or something. Oookay. Slowly fading away...
}
正如你可能会或可能没有注意到,我使用的Cars
类的类型名称,以确定在数据库中的表的名称。同样,我正在对Car
进行反思,并使用其公共属性名称和类型来获取/设置数据库中的值。是的,我知道我正在编写一个精简版的实体框架。这听起来既愚蠢又相当耗时。
不管怎么说,这是类Cars
,我必须提醒你的使用的例子,我的骄傲:
new Cars().Delete(3497); // Note that I have a great number of (expensive) cars.
不错,不是吗?一个小问题。这意味着我必须编写强类型代码,特定于数据库中存在的表的数量。我不喜欢特定的代码。我喜欢通用代码。
你可能会开始在这里争论我正在过度使用它。那么让我告诉你这一点。你真是太棒了我太过分了!我故意火焰喷射被坦克击倒的死人。七次。
于是我开始尝试了一下,用这种微妙的解决方案提出了:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod(EnableSession = true)]
public int CreateEmptyRow(string tableName)
{
var tableType = Type.GetType(tableName);
if (tableType == null)
throw new TypeLoadException("Dumbass. That table doesn't exist");
var instance = Activator.CreateInstance(tableType) as ITable<dynamic>;
if (instance == null)
throw new TypeLoadException("Idiot. That type isn't a table");
return instance.Insert(new DataRow());
}
请注意,如果你不知道我能真正理解为什么会有人想要创建一个空行。
那么这有什么问题呢?那么,它不会编译,一个。这是错误:There is no implicit reference conversion from 'dynamic' to 'DataRow'
。在Google上搜索了few results。
问题明显是Activator.CreateInstance(tableType) as ITable<dynamic>
。我试过了Activator.CreateInstance(tableType) as ITable<Table<DataRow>>
之类的东西,这个错误给了我一个错误:The type 'DataRow' must be convertible to 'DataRow'
。
关于改进我的解决方案的建议将奖励...奖励 – Simeon 2013-03-03 13:21:50
由于您已经知道您的Cars类实现了'ITable',您是否需要将其转换为接口?你能否简单地放弃'作为ITable '?我发现这篇文章在过去非常有帮助:[如何使用反射检查和实例化泛型](http://msdn.microsoft.com/zh-cn/library/b8ytshk6.aspx) –
plasticide
2013-03-03 13:24:27
解决方案的变化最少,也许不是最快/最有效的,将反映你想要调用的方法(而不仅仅是你实例化的类型) – YavgenyP 2013-03-03 13:29:27