如何在 C# 中使方法通用?

How to make a method generic in c#?

我有几种方法,而且还在不断扩展。所以,我打算让它通用。谁能帮我解决这个问题。至少方法定义。

private static Dictionary<string, class1> PToDictionary(MapField<string, class1Proto> keyValuePairs)
{
    Dictionary<string, class1> keyValues = new();
    foreach (var pair in keyValuePairs)
    {
       **keyValues[pair.Key] = pToR(pair.Value);**
    }
    return keyValues;
}

我的另一种方法是:

private static Dictionary<Uri, class2> PToDictionary1(MapField<string, class2Proto> keyValuePairs)
{
        Dictionary<string, class2> keyValues = new();
        foreach (var pair in keyValuePairs)
        {
           **keyValues[new Uri(pair.Key)] = pToR1(pair.Value);**
        }
        return keyValues;
}

我怎样才能使这个通用,以便在添加更多方法时,我不需要添加代码。 我在想这样的事情,但错误是:

//   Not sure how to call this method after Func is there
    private static Dictionary<TKey, TValue> PToDictionary<TKey, TValue, TKeyProto, TValueProto>(MapField<TKeyProto, TValueProto> keyValuePairs, Func<TKeyProto, TKey> keyFunc, Func<TValueProto, TValue> valueFunc)
{
   //How can I generalize my above method ?
}

有人可以帮我完成这个方法吗?

您可以使用以下方法将MapField<TKeyProto, TValueProto>转换为Dictionary<TKey, TValue>

public static Dictionary<TKey, TValue> PToDictionary<TKey, TValue, TKeyProto, TValueProto>(
    MapField<TKeyProto, TValueProto> keyValuePairs,
    Func<TKeyProto, TKey> mapKey,
    Func<TValueProto, TValue> mapValue
)
{
    Dictionary<TKey, TValue> keyValues = new();
    foreach (var pair in keyValuePairs)
    {
        keyValues[mapKey(pair.Key)] = mapValue(pair.Value);
    }
    return keyValues;
}

这里,mapKey是一个将MapField的键值转换为字典键值的函数。同样,mapValueMapField 的值转换为字典值。

另一种方法是使用 LINQ ToDictionary 扩展方法:

public static Dictionary<TKey, TValue> PToDictionary<TKey, TValue, TKeyProto, TValueProto>(
    MapField<TKeyProto, TValueProto> keyValuePairs,
    Func<TKeyProto, TKey> mapKey,
    Func<TValueProto, TValue> mapValue
)
{
    // this is possible because MapField<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>
    return keyValuePairs.ToDictionary(
        (KeyValuePair<TKeyProto, TValueProto> kvp) => mapKey(kvp.Key),
        (KeyValuePair<TKeyProto, TValueProto> kvp) => mapValue(kvp.Value));
}

例如,如果你想把MapField<string, string>转换成Dictionary<Uri, int>你可以使用下面的代码:

Dictionary<Uri, int> dictionary = PToDictionary(
    map,
    key => new Uri(key),
    val => int.Parse(val));

您根本不需要额外的方法。 LINQ 已经提供了你需要的一切,结合 MapField 实现 IDictionary<TKey, TValue> 的事实(因此 IEnumerable<KeyValuePair<TKey, TValue>>.

您只需拨打:

var dictionary = repeatedField.ToDictionary(
    pair => ConvertKey(pair.Key), pair => ConvertValue(pair.Value));

(其中 ConvertKey 是您想要将重复字段键转换为字典键的任何代码,ConvertValue 也是如此)。

调用示例:

var d1 = repeatedField1.ToDictionary(pair => pair.Key, pair => pToR(pair.Value));

var d2 = repeatedField2.ToDictionary(
    pair => new Uri(pair.Key), pair => pToR1(pair.Value));

...但是您仍然可以删除 pToRpToR1 方法。 (如果没有关于他们在做什么的信息,很难说...)