有人可以解释这个委托语法吗?

时间:2014-09-15 22:55:05

标签: c#

在名为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);
    }
}

3 个答案:

答案 0 :(得分:3)

  

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

这是一个委托,其类型为接受SqlDataReader作为输入的方法,并返回通用类型T作为结果。

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


  

C#是否足够智能以识别loadMethod需要传递给它的SqlDataReader,并且这样做 - 因为using语句和初始委托声明?因为否则我无法看到数据阅读器如何将其纳入方法中。

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

答案 1 :(得分:1)

声明public delegate T LoadObject<T>(SqlDataReader dataReader)期待SqlDataReader并将返回您想要的任何类型。可以是intList<string>甚至是其他代表。这是因为类型T上没有generic constraint,并且它只与代理的返回类型相关联。

另一方面,我们有private static KeyValuePair<string, string> _loadGroupType(SqlDataReader returnData)。这是一个接收SqlDataReader并返回...的函数...等等,它不重要,可能是任何东西!所以_loadGroupType确实&#34;匹配&#34;使用LoadObject<T> = T代理KeyValuePair<string, string>,可以隐式使用。

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

答案 2 :(得分:1)

首先声明说:LoadObject将采用SqlDataReader并返回T的方法,其中T由用户定义。

然后GetDictionaryFromReader表示它需要LoadObject<KeyValuePair<TKey, TValue>>,因此此处TKeyValuePair<TKey, TValue>,因此需要一个方法需要SqlDataReader并返回{{1 }}

最后,当您致电KeyValuePair<TKey, TValue>并传递GetDictionaryFromReader时,需要_loadGroupType并返回SqlDataReader,只需符合KeyValuePair<TKey, TValue>想要的内容。

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