Goo*_*ose 8 c# generics inheritance interface
我正在尝试创建一个通用的数据检索过程.我目前的工作,但有一部分似乎不正确,我希望有一个更好的方法来实现它.
所以我的想法是我为数据库中的每个表都有类,这里是一个类的例子:
public class CMCGRGRGROUP : IFacetsObject<CMCGRGRGROUP>
{
public int GRGR_CK { get; set; }
public string GRGR_NAME { get; set; }
public string GRGR_ADDR1 { get; set; }
public IEnumerable<CMCGRGRGROUP> ToObject(DataTable table)
{
return table.AsEnumerable().Select(row =>
{
return new CMCGRGRGROUP
{
GRGR_CK = Convert.ToInt32(row["GRGR_CK"]),
GRGR_NAME = row["GRGR_NAME"].ToString(),
GRGR_ADDR1 = row["GRGR_ADDR1"].ToString()
};
});
}
}
Run Code Online (Sandbox Code Playgroud)
您会注意到该类实现了自己类型的接口.接口只是定义了一个名为的方法ToObject,用于将数据表转换为该特定类型的类:
public interface IFacetsObject<T>
{
IEnumerable<T> ToObject(DataTable obj);
}
Run Code Online (Sandbox Code Playgroud)
现在,这是我用来执行查询的方法:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj) where T : new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return obj.ToObject(dt); //this is the interface method
}
}
Run Code Online (Sandbox Code Playgroud)
所以主要的问题是:
泛型方法如何知道T应该实现IFacetsObject<T>?这样我就不必IFacetsObject<T>作为参数传递.理想情况下,我可以将返回行更改为:
return T.ToObject(dt);
Run Code Online (Sandbox Code Playgroud)
并称之为:
var result = ExecuteQuery<CMCGRGRGROUP>(sql).Take(5);
Run Code Online (Sandbox Code Playgroud)
而不是像这样:
var result = ExecuteQuery<CMCGRGRGROUP>(sql, new CMCGRGRGROUP()).Take(5);
Run Code Online (Sandbox Code Playgroud)
我承认我对仿制药并不十分熟悉,因此实施中可能存在一些不正确的东西.
您可以在 ExecuteQuery 方法上添加约束。你已经有了一个:要求 T 是可更新的。你可以这样声明:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj)
where T : IFacetsObject<T>, new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return obj.ToObject(dt); //this is the interface method
}
}
Run Code Online (Sandbox Code Playgroud)
所以它现在知道 T 是一个IFacetsObject<T>. 你现在可以这样做:
public IEnumerable<T> ExecuteQuery<T>(string sql)
where T : IFacetsObject<T>, new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return new T().ToObject(dt); //this is the interface method
}
}
Run Code Online (Sandbox Code Playgroud)
哪个国际海事组织仍然很丑陋。
编辑回复:
请注意,您不能调用 T.ToObject - 接口不能定义静态方法。解决方法是使用 new 创建 T 的新实例并调用实例方法。
| 归档时间: |
|
| 查看次数: |
6901 次 |
| 最近记录: |