ParoX
ParoX

Reputation: 5933

Generic T to call overloaded functions

I want to do something like this:

public class Object1 {
    public int number{get;set;}
}
public class Object2 {
    public int number{get;set;} 
}

public class Object3 {
    public int number{get;set;} 
}

main();

public void main(){
    var objects1 = new List<Object1>{new Object1{number=1} , new Object1{number=2}};
     test<Object1>(objects1);
}

public List<Object3> test<T>(IEnumerable<T> objs){
    var rv = new List<Object3>();

    foreach (var o in objs)
    {
        var foo = overloaded(o);
        rv.Add(foo);
    }

    return rv;
}  

public Object3 overloaded(Object1 obj){
    // Run very specific things to Object1
    return new Object3{number=obj.number+1}; 
}

public Object3 overloaded(Object2 obj){
    // Run very specific things to Object2
    return new Object3{number=obj.number+2};    
}

You can directly run/edit the code here, with error handling: http://csharppad.com/gist/6ff5f13cac8f0e5735be

The error I get is Argument 1: cannot convert from 'T' to 'Object1' - So how can I do this? The idea is that Object1 and Object2 have 95% of their code identical, it's that last 5% that I need to have it do something specific for each.

Upvotes: 4

Views: 73

Answers (4)

dan
dan

Reputation: 532

Dependency Injection

interface IObject 
{
   int number {get;set;}
}

public class Object1 : IObject {
    public int number{get;set;}
}
public class Object2 : IObject  {
    public int number{get;set;} 
}

public class Object3 : IObject  {
    public int number{get;set;} 
}

public IObject overloaded(IObject obj){
    // Run very specific things to Object1
    return new IObject {number=obj.number+1}; 
}

Upvotes: 0

Bojan Resnik
Bojan Resnik

Reputation: 7378

You could use dynamic to in your test method, just note that there are performance implications:

overloaded((dynamic)obj);

Upvotes: 1

ParoX
ParoX

Reputation: 5933

After playing around I was able to come up with this

public class Object1 {
    public int number{get;set;}
}
public class Object2 {
    public int number{get;set;} 
}

public class Object3 {
    public int number{get;set;} 
}

main();

public void main(){
    var objects1 = new List<Object1>{new Object1{number=1} , new Object1{number=2}};
     test<Object1>(objects1);
}


public List<Object3> test<T>(IEnumerable<T> objs){
    var rv = new List<Object3>();

    foreach (var o in objs)
    {
        if(typeof(T) == typeof(Object1)){
            rv.Add(overloaded((Object1)(object)o));
        } else {
            rv.Add(overloaded((Object2)(object)o));
        }
    }

    return rv;
}


public Object3 overloaded(Object1 obj){
    return new Object3{number=obj.number+1}; 
}

public Object3 overloaded(Object2 obj){
    return new Object3{number=obj.number+2};    
}

This works, but seems hacky to me. Wondering what the best way is!

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 190907

I would reverse your thinking.

Try this:

private void test<T>(T obj){
    // Do common stuff

}
public void overloaded(Object1 obj){
    test(obj);
    Console.WriteLine("Do Object 1 stuff");   
}
public void overloaded(Object2 obj){
    test(obj);
    Console.WriteLine("Do Object 2 stuff");   
}

and call overloaded instead of calling test.

Upvotes: 0

Related Questions