gpt4 book ai didi

c# - T 实现 Interface 的通用方法

转载 作者:太空狗 更新时间:2023-10-29 19:44:03 28 4
gpt4 key购买 nike

我正在尝试创建一个通用的数据检索过程。我目前所做的工作有效,但其中有一部分似乎不正确,我希望有更好的方法来完成它。

所以我的想法是为数据库中的每个表创建类,这是一个类的示例:

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()
};
});
}
}

您会注意到该类实现了它自己类型的接口(interface)。该接口(interface)简单地定义了一个名为 ToObject 的方法。 ,用于将数据表转换为该特定类型的类:

public interface IFacetsObject<T>
{
IEnumerable<T> ToObject(DataTable obj);
}

现在,这是我用来执行查询的方法:

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
}
}

所以主要问题是:泛型方法如何知道 T 应该实现 IFacetsObject<T> ?这样我就不必通过 IFacetsObject<T>作为参数。理想情况下,我可以将返回行更改为如下所示:

return T.ToObject(dt);

然后这样调用它:

var result = ExecuteQuery<CMCGRGRGROUP>(sql).Take(5);

而不是像这样:

var result = ExecuteQuery<CMCGRGRGROUP>(sql, new CMCGRGRGROUP()).Take(5);

我承认我对泛型还不是很熟悉,所以在实现中可能有些地方不对。

最佳答案

您可以在 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
}
}

所以它现在知道 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
}
}

哪个 IMO 仍然很丑陋。

编辑响应:

请注意,您不能调用 T.ToObject - 接口(interface)不能定义静态方法。解决方法是使用 new 创建 T 的新实例并调用实例方法。

关于c# - T 实现 Interface<T> 的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22616560/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com