1

I have a function that takes in a generic type and I want to be able to assign the result of some computation to different lists depending on that type. I'd rather not use reflection because I've learned that it's not exactly best practice.

Here is the gist of what I have so far:

private List<int> List1 = new List<int>();
private List<int> List2 = new List<int>();
private List<int> List3 = new List<int>();

public int SomeFunction<TModel, TEntity>(DbSet<TEntity> context) where TEntity : class where TModel : SuperModel
{
    // TEntity could be one of three types: Type1, Type2, or Type3
    // If TEntity is of Type1, I want to be able to add something to List1.
    // If TEntity is of Type2, I want to be able to add something to List2.  And so on.

    /* One way to do it */

    // ... do some function stuff calculation here...
    var result = ...

    Type entity_type = typeof(TEntity)
    if (entity_type == typeof(Type1)) 
        List1.Add(result);
    else if (entity_type == typeof(Type2))
        List2.Add(result);
    else if (entity_type == typeof(Type3))
        List3.Add(result);
}

However, I don't think this is the best way as it relies on reflection for run-time calculation. Is there a way to do it using interfaces or polymorphism?

Another way is to have split this up into three functions, have Type1, Type2, Type3 implement three different interfaces and then add a where TEntity : IType1, where TEntity: IType2, and where TEntity: IType3 following each of the three function headings.

This doesn't seem to be right either. Any help would be greatly appreciated.

noblerare
  • 10,277
  • 23
  • 78
  • 140
  • 3
    Sort of defeats the purpose of a _generic_ doing that. Generics should be agnostic and not have knowledge of the concrete type as it limits its usefulness –  Apr 06 '18 at 01:49
  • Your example code, while not terribly elegant, does not rely on reflection at all. – Mike Strobel Apr 06 '18 at 01:49
  • @MickyD so would it be better to make this a virtual function in an interface and have my types implement that interface and supply code for their own version of that function? – noblerare Apr 06 '18 at 01:58
  • @noblerare If that's possible with what you're doing, that would be a much better option. – ProgrammingLlama Apr 06 '18 at 02:00
  • 2
    It sort of looks like you might be better off doing away with the generic-ness and simply have 3 different methods, one for `Type1`, `Type2` and `Type3`. Would be faster too –  Apr 06 '18 at 02:00

3 Answers3

3

There isn't really many options with what you describe

  • Make 3 methods
  • Use an IF
  • Use pattern matching
  • Use reflection, though i'm not really sure why
  • You could also use a switch

Example

switch typeof(e) { 
        case int:    ... break; 
        case string: ... break; 
        case double: ... break; 
        default:     ... break; 
}

Or you could make the class generic

public class SomeClass<T> where T : something
{

    private List<T> List3 = new List<T>();

    public int SomeFunction<TModel, T>(DbSet<T> context)
    {
        // do stuff
    }
}
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
0

You can use pattern matching with the is keyword:

if (context is DbSet<Type1>) 
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
0

You could use a dictionary

Dictionary < Type , dynamic > d(custom_equality_comp)

D.[entity_type].Add(result)

Haven't worked with c# in a while but this worth a try. You initialize the dictionary in the constructor and then go from there. References.

Efficiency of using IEqualityComparer in Dictionary vs HashCode and Equals()

Dictionary of generic lists or varying types

List<Object> vs List<dynamic>

Potato
  • 628
  • 5
  • 8