[英]Which is the right way to know type of the argument passed to the generic method in C#?
從我的C# 4.0
代碼中,我想在Sybase
和MSSQL
上執行一些查詢。 正在使用(或將要使用)的數據庫僅在運行時才確定/已知。
我分別使用Sybase和SQL的AseCommand
和SqlCommand
。
我決定創建這樣的通用方法:
private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
Department department = new Department ();
dynamic command = databaseCommand;
using (dynamic databaseReader = command.ExecuteReader())
{
if (databaseReader.HasRows)
{
while (databaseReader.Read())
{
department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
問題:
dynamic
以外,還有更好的選擇嗎? dynamic
事情呢? 您在這里不一定需要動態的,您需要的只是一個公共接口(在這種情況下,它們都具有):
private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
但是,在這種情況下,由於您沒有對T
類型做任何特別有趣的事情(據我所知),因此以下方法簽名就足夠了:
private Department ExecuteCommand(IDbCommand databaseCommand)
通常,如果沒有通用接口,我建議您使用Facade模式,並簡單地將方法調用委派給實際實現的等效項。
看起來AseCommand
和SqlCommand
都實現了IDbCommand
,因此您只需要更改類型約束即可:
private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
{
Department department = new Department();
using (IDataReader databaseReader = databaseCommand.ExecuteReader())
{
if (databaseReader.HasRows)
{
while (databaseReader.Read())
{
department.Employees.Add(
this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
假設您還需要更改CreateDepartmentInstance
以接受IDataReader
如果尚未接受)。
盡管正如rich.okelly指出的那樣,但實際上並沒有理由首先在這里使用泛型。
回答#2:
if (typeof(T) == typeof(object) ) {
// Check for IEnumerable
}
用您要檢查的任何類型替換對象。
在您的情況下,使用通用接口就可以了。
一般來說,如果你想找出一個對象的類型,你可以隨時使用的is
和as
-Operators。
private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
Department department = new Department ();
var command = databaseCommand;
using (var databaseReader = command.ExecuteReader())
{
if ((databaseReader as IDataReader).HasRows)
{
while ((databaseReader as IDataReader).Read())
{
department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
尚未在VS中驗證,但應該可以。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.