C#通过函数传递参数,作为参数并返回通用类型

问题描述 投票:1回答:1

在下面的代码中,我试图将函数“ func”传递给GetData函数。这将采用阅读器对象并将其映射到通用对象。

我希望将一个对象类型和一个将数据映射到该对象类型的函数传递给GetData,因此我不必重复打开/关闭/释放连接。

这有可能还是有人有其他建议吗?

非常感谢

尼克

public T GetData<T>(string cmdText,Func<T> func)
        {
            using (SqlConnection conn = new SqlConnection(connectionStringBuilder.ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand(cmdText, conn))
                {
                    SqlDataReader reader = cmd.ExecuteReader();
                    //return func(reader);                    
                    //  WITHIN THE FUNC FUNCTION:
                    //  while (reader.Read())
                    //  {
                    //  Map function to T e.g
                    //  T.property = reader["column"];
                    //  Return T
                    //  }
                }
            }
        }
c# generics lambda sqldatareader
1个回答
0
投票

您正在寻找的签名是这个:

T GetData<T>(string cmdText, Func<SqlDataReader, T> func)

然后您可以继续编写函数,如下所示:

public T GetData<T>(string cmdText, Func<SqlDataReader, T> func)
{
    using (var conn = new SqlConnection(connectionStringBuilder.ConnectionString))
    {
        using (var cmd = new SqlCommand(cmdText, conn))
        {
            var reader = cmd.ExecuteReader();
            return func(reader);
        }
    }
}

您会这样使用它:

var result = GetData("select * from Foo", dr =>
{
    while (dr.Read())
    {
        return new { property = dr["column"] };
    }
    throw new DataException();
});

现在,这是基于您说的在问题中的使用方式。

但是,在拆分实现时,您已经有点难以使用该功能了-部分在GetData中,而一部分在调用代码中。

最好使用此签名:

IEnumerable<T> GetData<T>(string cmdText, Func<SqlDataReader, T> func)

现在您可以编写这样的方法:

public IEnumerable<T> GetData<T>(string cmdText, Func<SqlDataReader, T> func)
{
    using (var conn = new SqlConnection(connectionStringBuilder.ConnectionString))
    {
        using (var cmd = new SqlCommand(cmdText, conn))
        {
            var reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                yield return func(reader);
            }
        }
    }
}

现在的优点是调用代码更加简单:

var results = GetData("select * from Foo", dr => new { property = dr["column"] });

这将返回查询返回的数据行。

如果知道调用代码仅返回一个值,则可以在方法调用的末尾放一个.Single()以确保只得到一个结果。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.