Create C# Generic Method Mapping To Object Instance Lists
Problem
I'm attempting to create one or more generic C# methods that operate over a Dictionary<long, string>,
capable of mapping (long)Key
& (string)Value
to
compatible IEnumerable<T>
objects. Where T
will be a class with two properties: (long)Id
& (string)Value
.
I'm not limited very much in terms of how I can approach the problem. The main goal is for the data structure to be mappable to classes sharing that shape. I've included code signatures/snippets as a rough outline.
Outline
1. Input Shape
2. Output Shape
3. Method Shape
CodePudding user response:
In a generic method, you can only do things with a reference of type T
that you know about type T
. How are you supposed to know that type T
has those properties? The only way is for them to be declared in a common base class or interface and then you can constrain T
to be that type.
For instance, you might have this interface:
public interface IThing
{
long Id { get; set; }
string Name { get; set; }
}
You can then write this method:
public void DoSomething<T>(T arg) where T : IThing
{
arg.Id = 0L;
arg.Name = "Hello";
}
You can access those members in the method because of the constraint, which means that only objects whose type implements the IThing
interface can be passed to that method.
If all the types you want to map to don't inherit a common base type or implement a common interface then you're out of luck.
CodePudding user response:
The method you want already exists - the LINQ Select
extension. (using System.Linq;
)
Dictionary<long, string>
implements IEnumerable<KeyValuePair<long,string>>
. It already is a collection of objects with a long
and string
property.
With Select
you can map those key/value pairs to a different type.
IEnumerable<MyClass> myResult =
myDict.Select(keyValuePair =>
new MyClass {Id = keyValuePair.Key, Name = keyValuePair.Value});
You're passing a in function that takes a KeyValuePair<long,string>
and returns something - in this case an instance of MyClass
. That function is
keyValuePair =>
new MyClass {Id = keyValuePair.Key, Name = keyValuePair.Value}
...which is an anonymous function (it's just declared, it has no name) and the equivalent of
MyClass CreateFromKeyValuePair(KeyValuePair<long,string> keyValuePair)
{
return new MyClass {Id = keyValuePair.Key, Name = keyValuePair.Value};
}
Select
passes each item in the source (in this case, an IEnumerable<KeyValuePair<long,string>>
) and returns an IEnumerable<T>
where T
is whatever the function returns.