C# 使用func时,我能否以任何方式更改签名<&燃气轮机;代表?

C# 使用func时,我能否以任何方式更改签名<&燃气轮机;代表?,c#,.net,c#-4.0,C#,.net,C# 4.0,我有一个数据访问层名称空间,其中包含大量重复代码(主要是设置命令对象和执行存储过程以返回添加到列表中的数据集)。我正在尝试编写一个返回列表的通用工厂方法。我对泛型和委托都比较陌生。我的想法是使用Func参数创建添加到列表中的对象。它将在通常的while dataReader.Read()块中调用。我的问题是,我将使用的数据集具有不同的列数 以下是我到目前为止的情况: private static List<T> ListFromDatabase<T,U>(String C

我有一个数据访问层名称空间,其中包含大量重复代码(主要是设置命令对象和执行存储过程以返回添加到列表中的数据集)。我正在尝试编写一个返回
列表的通用工厂方法。我对泛型和委托都比较陌生。我的想法是使用Func参数创建添加到
列表中的对象。它将在通常的
while dataReader.Read()块中调用。我的问题是,我将使用的数据集具有不同的列数

以下是我到目前为止的情况:

private static List<T> ListFromDatabase<T,U>(String CommandName, SqlConnection SqlConn, Func<T,U> CreateListObj, 
    List<SqlParameter> ParamList = null)
{
    List<T> returnList = new List<T>();

    using (SqlCommand cmd = new SqlCommand(CommandName,SqlConn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        foreach (SqlParameter sp in ParamList)
        {
            if (sp.Value == null)
                sp.Value = DBNull.Value;
            cmd.Parameters.Add(sp);
        }

        SqlDataReader sdr = cmd.ExecuteReader();
        while (sdr.Read())
        {
            returnList.Add(CreateListObj);
        }
    }

    return returnList;
}
private static List ListFromDatabase(字符串CommandName、SqlConnection SqlConn、Func CreateListObj、,
列表参数(列表=空)
{
List returnList=新列表();
使用(SqlCommand cmd=newsqlcommand(CommandName,SqlConn))
{
cmd.CommandType=CommandType.storedProcess;
foreach(参数列表中的SqlParameter sp)
{
如果(sp.Value==null)
sp.Value=DBNull.Value;
cmd.Parameters.Add(sp);
}
SqlDataReader sdr=cmd.ExecuteReader();
while(sdr.Read())
{
returnList.Add(CreateListObj);
}
}
退货清单;
}
在我目前的理解水平上,这可能是不可能的,因为我可能需要为不同数量的参数改变Func签名。这是可行的,还是接近的?如果没有,我愿意接受不同的方法,如果有人能帮忙的话。非常感谢

更新:这正是我想要的:


最优雅的方法是将T指定为
元组
,方法是传递一个函数,该函数接受具有特定数量和类型项的元组,然后使用Tuple.Create使用sdr中的行内容生成该元组。问题是,当从DataReader中获取字段时,字段会显示为类型不确定的对象,当您不知道字段的真实类型时,传递字段的最安全方式是字符串,这意味着CreateListObj函数必须预期字符串并能够正确解析它们(因此在元组中预期特定的列顺序).

为什么不将您的
SqlDataReader
作为
IDataRecord
传递给您的学员?委托人可以从数据记录中获得所需信息;您可以控制对读取器的迭代。

我过去所做的是定义“builder”方法,这些方法采用
IDataReader
,并返回它们定义的对象类型(我将它们作为泛型类的方法而不是委托,但
Func
也会这样做)

通常,我在
ExecuteReader
调用中使用了
CommandBehavior.CloseConnection
,然后返回一个类,该类保存在读卡器上,实现了
IEnumerable
,然后在释放读卡器时关闭读卡器(以及底层连接),而不是首先创建整个列表(如果枚举器实际上根本没有枚举,则必须小心清理它)


其优点是,我不必在定义时担心列数和类型的差异,只需在实现时(在实现时我会情不自禁地担心).

我会做一些类似于你提议的事情。我想知道,你对你的实施有什么不满意?@BrianDishaw我不知道如何“充实”/实现func委托,特别是因为参数的#会有所不同。
U
类型参数是什么?这不会编译,因为您正试图将
func
添加到
列表中。听起来您想要
func
并将读取器传递给func,以创建
t
?@L的实例ee是的,不会编译,这就是我被卡住的地方。。我知道U现在还没有解释。。你的建议很接近,但是我必须在为委托传递的函数中进行迭代,我希望在工厂发生的迭代中调用委托。@StatsViaCsh-迭代将在
列表fromdat中进行abase
method:
while(sdr.Read()){returnList.Add(func(sdr));}
我对IDataRecord不太熟悉。现在看看这个,thx。有趣的方法,我不知道我是否能完全按照您描述的方式实现它,但我会尝试一下。