有人能解释一下这个委托语法吗

本文关键字:语法 一下 能解释 | 更新日期: 2023-09-27 18:22:08

在一个名为DataAccess的类库中,我发现了以下声明和用法:

public static class DataAccess
{
    public delegate T LoadObject<T>(SqlDataReader dataReader);
    public static Dictionary<TKey, TValue> GetDictionaryFromReader<TKey, TValue>(
        Database database
        , DbCommand dbCommand
        , LoadObject<KeyValuePair<TKey, TValue>> loadMethod
        )
    {
        Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
        using (SqlDataReader dataReader = StoredProcedures.ExecuteSqlDataReader(database, dbCommand))
        {
            GenerateDictionary<TKey, TValue>(dataReader, ref _dictionary, loadMethod);
        }
        return _dictionary;
    }
}

GetDictionaryFromReader通过以下静态方法调用:

public static Dictionary<String, String> GetGroupTypesList()
{
    Dictionary<string, string> dict = new Dictionary<string, string>();
    Database database = CenestDatabaseFactory.CreateDatabase();
    DbCommand dbCommand = database.GetStoredProcCommand(SP_LIST_GROUP_TYPES);
    dict = DataAccess.GetDictionaryFromReader<string, string>(database, dbCommand, _loadGroupType);
    return dict;
}

它将"_loadGroupType"传递到"loadMethod"中。"_loadGroupType"如下所示:

private static KeyValuePair<string, string> _loadGroupType(SqlDataReader returnData)
{
    KeyValuePair<string, string> entry =
        new KeyValuePair<string, string>((string)returnData["Group_Type"], (string)returnData["Group_Type_Desc"]);
    return entry;
}

我有点"了解"到_loadGroupType方法正作为参数传递到GetDictionaryFromReader中。好吧,但为什么?这个委托声明语法应该说什么?

public delegate T LoadObject<T>(SqlDataReader dataReader);

我真的很想了解这是怎么回事。你不需要自己解释,但你能指出一些能让我明白的东西吗?

谢谢!

@ReedCopsey的附加说明:

所以。。。

在此使用声明中:

using (SqlDataReader dataReader = StoredProcedures.ExecuteSqlDataReader(database, dbCommand))
{
    GenerateDictionary<TKey, TValue>(dataReader, ref _dictionary, loadMethod);
}

C#是否足够聪明,能够识别loadMethod需要传递给它的SqlDataReader,并且这样做是因为using语句和初始委托声明?因为除此之外,我看不出数据读取器是如何将其纳入方法的。

当然不是!根据@ReedCopsey,GenerateDictionary方法使用SqlDataReader,Duh:

private static void GenerateDictionary<TKey, TValue>(
    SqlDataReader dataReader
    , ref Dictionary<TKey, TValue> dictionary
    , LoadObject<KeyValuePair<TKey, TValue>> loadMethod
    )
{
    while (dataReader.Read())
    {
        KeyValuePair<TKey, TValue> kvp = loadMethod(dataReader);
        dictionary.Add(kvp.Key, kvp.Value);
    }
}

有人能解释一下这个委托语法吗

这个委托声明语法应该说什么?

这是一个委托,它被类型化为接受SqlDataReader作为输入的方法,并返回泛型类型T作为结果。

在您的情况下,T的结果是KeyValuePair<string,string>


C#是否足够聪明,能够识别loadMethod需要传递给它的SqlDataReader,并且这样做是因为using语句和初始委托声明?因为除此之外,我看不出数据读取器是如何将其纳入方法的。

没有。GenerateDictionary<TKey,TValue>方法将使用传递给它的dataReader来调用委托。

声明public delegate T LoadObject<T>(SqlDataReader dataReader)需要一个SqlDataReader,并将返回您想要的任何类型。可能是intList<string>,甚至是另一个委托。这是因为类型T上没有通用约束,它只与委托的返回类型相关联。

另一方面,我们有private static KeyValuePair<string, string> _loadGroupType(SqlDataReader returnData)。这是一个接收SqlDataReader并返回…等等,没关系,可以是任何东西!因此,_loadGroupType确实与委托LoadObject<T>"匹配",T=KeyValuePair<string, string>,并且可以隐式使用。

如果有一个声明为delegate KeyValuePair<string, string> D2(SqlDataReader reader);的委托,它也会匹配,但这次没有泛型。当类型对操作不重要时(或者可以限制它),泛型就是你的朋友。

首先声明:LoadObject将是一个接受SqlDataReader并返回T的方法,其中T由用户定义。

然后GetDictionaryFromReader说它需要一个LoadObject<KeyValuePair<TKey, TValue>>,所以T在这里是KeyValuePair<TKey, TValue>,所以它需要一种方法获取SqlDataReader并返回KeyValuePair<TKey, TValue>

最后,当您调用GetDictionaryFromReader,传递_loadGroupType时,它会得到一个SqlDataReader并返回KeyValuePair<TKey, TValue>,正好符合GetDictionaryFromReader的要求。

我不认为有什么难以理解的。