I have couple of methods and it keeps on expanding. So, I am planning to make it generic. Can anyone please help me with that. Atleast the method definition.
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;
}
My another method is :
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;
}
How can I make this generic so that when more methods are added, I dont need to add code. I was thinking something like this, but errors are :
// 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 ?
}
Can someone help me complete the method ?
CodePudding user response:
You don't need an extra method at all. LINQ already provides everything you need, combined with the fact that MapField
implements IDictionary<TKey, TValue>
(and therefore IEnumerable<KeyValuePair<TKey, TValue>>
.
You'd just call:
var dictionary = repeatedField.ToDictionary(
pair => ConvertKey(pair.Key), pair => ConvertValue(pair.Value));
(where ConvertKey
would be whatever code you want to convert the repeated field key into the dictionary key, and likewise for ConvertValue
).
Sample calls:
var d1 = repeatedField1.ToDictionary(pair => pair.Key, pair => pToR(pair.Value));
var d2 = repeatedField2.ToDictionary(
pair => new Uri(pair.Key), pair => pToR1(pair.Value));
... but you may be able to remove the pToR
and pToR1
methods anyway. (It's hard to tell without information about what they're doing...)
CodePudding user response:
You can use the following method to convert MapField<TKeyProto, TValueProto>
to 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;
}
Here, mapKey
is a function that converts MapField
's key to a dictionary key. Similarly, mapValue
converts MapField
's value to a dictionary value.
Another way is to make usage of LINQ ToDictionary extension method:
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));
}
For example, if you want to convert MapField<string, string>
to Dictionary<Uri, int>
you can use the following code:
Dictionary<Uri, int> dictionary = PToDictionary(
map,
key => new Uri(key),
val => int.Parse(val));
CodePudding user response:
Just replace your types with generic type parameters:
private static Dictionary<T1, T2> PToDictionary<T1, T2>(MapField<T1, T2> keyValuePairs)
{
Dictionary<T1, T2> keyValues = new();
foreach (var pair in keyValuePairs)
{
keyValues[pair.Key] = pToR(pair.Value);
}
return keyValues;
}
Note that
PToDictionary<TKey, TValue>(MapField<TKeyProto,TValueProto> m1, Func<Tkey>(TKeyProto) keyFunc, Func<TValue>(TValueProto) valueFunc)
is just incorrect.
First of all Func<Tkey>(TKeyProto)
is not correct syntax, it should be Func<TKeyProto, Tkey>
to declare a function taking a TKeyProto
, and returning a TKey
. You also need to declare all generic type parameters, i.e. PToDictionary<TKey, TValue, TKeyProto, TValueProto>
. Buy you might as well just use the existing .ToDictionary extension method