I have written the following method:
public static Dictionary<K, V> ListToDictionary<E, K, V>(
List<E> list, Func<E, K> keyProvider, Func<E, V> valueProvider)
{
Dictionary<K, V> dictionary = new Dictionary<K, V>();
foreach (E e in list)
{
K key = keyProvider(e);
V value = valueProvider(e);
dictionary.Add(key, value);
}
return dictionary;
}
This method takes in a list and transforms it into a dictionary using the given functions to extract keys and values from the list elements. Now, to shorten things I have the following interface:
public interface IKeyValueProvider<K, V>
{
K GetKey();
V GetValue();
}
And an overload of the method mentioned above, looking like this:
public static Dictionary<K, V> ListToDictionary<E, K, V>(List<E> list) where E : IKeyValueProvider<K, V>
{
return ListToDictionary(list, x => x.GetKey(), x => x.GetValue());
}
I hoped that I could use this construction as follows:
Utils.ListToDictionary(someList)
Where someList is a List and E is a type (in my case, a struct) implementing IKeyValueProvider with concrete type parameters for K and V. But this does not seem to be possible since I get the error
The type arguments for method 'Dictionary Roadster.Other.Utils.ListToDictionary(List)' cannot be inferred from the usage.
Why is C# not able to infer the type arguments in such a scenario? Am I missing something obvious, which is the reason why they are not unique in this case, or is this simply not supported?
Edit: Sorry for the missing transparency of my "does not work" claim. Here is an example of how I try to use that functionality. I am a C# beginner, so maybe I am doing things fundamentally wrong. So here is the example:
The struct, implementing IKeyValueProvider:
public struct A : IKeyValueProvider<string, string>
{
public string s1;
public string s2;
public string GetKey() => s1;
public string GetValue() => s2;
}
Usage of the method:
public void TestMethod()
{
A a1 = new A { s1 = "test", s2 = "banana" };
A a2 = new A { s1 = "serh", s2 = "weiougnw" };
List<A> aList = new List<A> { a1, a2 };
Dictionary<string, string> test = Utils.ListToDictionary(aList);
}
As I am assigning the result to a Dictionary explicitly, I would expect the arguments to be inferable here.