我已將自己編碼到一個角落,並希望您的幫助能夠再次挖掘我。在正確的方向。在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