Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile-Time Generic Type Mapping without Reflection

In C#, is there any way to map one generic type to another generic type during compile time? I'd like to avoid using Reflection for this question. For example, let's say I would like to have TypeA map to TypeB, and have something similar to the following code work:

private void List<U> GetItemList<T>() where T : class <== U is the destination type obtained by the compile-time mapping from T to U
{
    Type U = GetMappedType(typeof(T))   <=== this needs to happen during compile-time
    List<U> returnList = Session.QueryOver<U>().List();
    return returnList;
}

private Type GetMappedType(Type sourceType)
{
    if (sourceType == typeof(TypeA))
        return typeof(TypeB);
}

I realize that since I'm using a method call to map the type, that it will not do the mapping during compile time, but is there another way that accomplishes what I'm trying to achieve, only during compile time? I know that the code above is not correct, but I hope you can see what I'm trying to go for.

In short, I'd like to know if there's a way to map one type to another and have the C# compiler know the type mapping so that the destination type can be used as a Generic Type Parameter to any method that takes a Generic Type Parameter. I'd like to avoid using Reflection.

As a side-question, if I do use Reflection for this, will it make the implementation very resource-heavy?

like image 899
Anshul Avatar asked May 06 '26 12:05

Anshul


1 Answers

Yes dynamic would be the answer. I had the same issue recently where I had to switch repositories based on some values configured in the database.

var tableNameWithoutSchema = tableName.Substring(tableName.IndexOf(".", StringComparison.Ordinal) + 1);
var tableType = string.Format("Library.Namespace.{0}, Library.Name", tableNameWithoutSchema);
var instance = UnitofWork.CreateRepository(tableType, uoW);

CreateRepository returns a dynamic type

public static dynamic CreateRepository(string targetType, DbContext context)
{
    Type genericType = typeof(Repository<>).MakeGenericType(Type.GetType(targetType));
    var instance = Activator.CreateInstance(genericType, new object[] { context });
    return instance;
}

context was needed as I had to pass the context to Generic repository through constructor. In my case this approach had some problems though. May be this helps you.

like image 108
Nilesh Avatar answered May 08 '26 02:05

Nilesh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!