0

I would like to create a generic method that can convert an object to a different type. I could not find any solutions for this scenario. Is this possible in C#?

class A
{
    public string Name { get; set; }
}

class A1: A
{
    public string ConnectionString { get; set; }
}

class B
{
    public string DBName { get; set; }
    public string DBConnectionString { get; set; }
}

void Main()
{
    A obj = //data
    var res = APIToBackEndModel<A, B>(obj);

    //Do something
    A1 obj1 = //data
    var res1 = APIToBackEndModel<A1, B>(obj1);
}

private TResult APIToBackEndModel<T, TResult>(T objTo)
{
    (TResult)DBName = (T)objTo.Name;

    //OR

    var obj = new TResult
    {
        DBName = (T)objTo.Name
    }
}

This did not help me.

Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
prvn
  • 406
  • 3
  • 7
  • 24
  • 3
    what are the `T` you want to use this with? do they all have a `Name`? would a common base-type or interface be useful? (generics supports constraints on the type parameters). What `TResult` do you need? basically, can we see some real examples? – Marc Gravell Aug 08 '18 at 15:27
  • 1
    This sounds suspiciously like an [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). What are you actually intending to use this function for? – Abion47 Aug 08 '18 at 15:39
  • @MarcGravell I updated the question – prvn Aug 08 '18 at 15:49
  • 1
    Are you looking for something like [AutoMapper](http://automapper.org/) or libraries like that? – Hans Kesting Aug 08 '18 at 15:51
  • @HansKesting adding Automapper to project will it not be heavy for this functionality? it would be better for me to create two methods to map instead. – prvn Aug 08 '18 at 15:57

1 Answers1

1

You won't be able to do it completely generic, as you rely on certain properties to exist. But you knowing these properties exist, is not enough. You have to guarantee the compiler, they exist. You can do this with Constraints on type parameters. With their help, you can define, that the generic types you use, will have certain properties (for instance implement an interface or inherit from a class).

interface InterfaceIn {
    string p1 {get;set;}

    void m1();
}

interface InterfaceOut {
     string p2 {get;set;}
     void m2();
}

class ConcreteIn : InterfaceIn {

    public string p1 {get;set;}
    public void m1() {}
}

class ConcreteOut1 : InterfaceOut {
    public string p2 {get;set;}
    public void m2() {}
}


class ConcreteOut2 : InterfaceOut {
    public string p2 {get;set;}
    public void m2() {}

}

class Program
{
    static void Main(string[] args)
    {
        var a = new ConcreteIn{p1 = "some value"};
        var b = mapIt<ConcreteIn, ConcreteOut1>(a);
        var c = mapIt<ConcreteIn, ConcreteOut2>(a);
    }

    public static V mapIt<U, V>(U val) where U: InterfaceIn where V: InterfaceOut, new() {
        var res = new V {p2 = val.p1};
        return res;
    }
}

Depending on how much properties and combinations you have, this may be enough. Or you may be better off with something like Automapper as Hans Kesting suggested. Or, if you can't group together some mappings, you will have to implement every mapping yourself.

derpirscher
  • 14,418
  • 3
  • 18
  • 35