Home > Enterprise >  Create C# Generic Method Mapping To Object Instance Lists
Create C# Generic Method Mapping To Object Instance Lists

Time:10-26

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

Starting Data Structure

2. Output Shape

enter image description here

3. Method Shape

enter image description here

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.

  • Related