1

I have a dictionary of class types that looks like this:

    private static Dictionary<int, Type> GetArrayOfClassInstances()
    {
        var availability = new LeisureLinkBaseProduct.Availability();
        var baseRate = new LeisureLinkBaseProduct.BaseRate();
        var stayRestrictions = new LeisureLinkBaseProduct.StayRestrictions();
        var checkInInformation = new LeisureLinkBaseProduct.CheckInInformation();
        var specials = new LeisureLinkBaseProduct.Specials();
        var taxes = new LeisureLinkBaseProduct.Taxes();
        var fees = new LeisureLinkBaseProduct.Fees();

        var classDictionary = new Dictionary<int, Type>();
        classDictionary.Add(1, availability.GetType());
        classDictionary.Add(2, baseRate.GetType());
        classDictionary.Add(3, stayRestrictions.GetType());
        classDictionary.Add(4, checkInInformation.GetType());
        classDictionary.Add(5, specials.GetType());
        classDictionary.Add(6, taxes.GetType());
        classDictionary.Add(7, fees.GetType());

        return classDictionary;
    }

And I want to pass it into this generic method that looks like this:

                var classes = GetArrayOfClassInstances();

                foreach (var instance in classes)
                {
                    var request = RequestBuilder.BuildAdditionalDataRequest(link.href);
                    var response = Api<instance.value>(request.Endpoint);
                }

but I get the intellisense error "instance is a variable but is used like a type" how do I pass this class type into the generic then? Is this possible? Thanks!

Adam Weitzman
  • 1,552
  • 6
  • 23
  • 45
  • 1
    As a total aside to your question, you dont need to create an instance to get its type, you can do (for example) `var taxes = typeof(LeisureLinkBaseProduct.Taxes);` – Jamiec Jun 14 '16 at 15:57
  • o nice that's way better then what I was doing – Adam Weitzman Jun 14 '16 at 15:58
  • 1
    [this question](http://stackoverflow.com/questions/266115/pass-an-instantiated-system-type-as-a-type-parameter-for-a-generic-class?rq=1) talks about instantiating a generic class with a `Type` instance, but the process will be similar if `Api` in your code is a method call. – Jamiec Jun 14 '16 at 16:00
  • 1
    If you use @Jamiec's answer then you end up with an `object` back. If you must cast this object to a type anyway then you haven't gained anything with that answer; instead of `switch`'ing over generic `Api` method calls you are `switch`'ing over a bunch of returned `object`'s to cast them. – Quantic Jun 14 '16 at 16:04
  • Exactly, I was skirting over the point that generics are great when you know the type at compile time and near-on useless if you dont (for the reason @Quantic mentions) – Jamiec Jun 14 '16 at 16:05
  • right got that, do you have to pass the literal class type into the generic though? – Adam Weitzman Jun 14 '16 at 16:06
  • @AdamWeitzman yes - you would do `Api(...)` – Jamiec Jun 14 '16 at 16:06
  • @AdamWeitzman: Were you able to solve this? – poppertech Jun 17 '16 at 19:41
  • 1
    yes sorry your answer worked! – Adam Weitzman Jun 17 '16 at 21:43

2 Answers2

0

You will need reflection as the type is not known at compile-time:

typeof(Api<>).MakeGenericType(instance.value)
    .GetConstructor(new[] {typeof(Endpoint)})
    .Invoke(new[]{request.Endpoint});
Florian Doyon
  • 4,146
  • 1
  • 27
  • 37
0

The following ran for me and is based on this post:

Api Class:

public class Api<T>
{
    public Api(Type E){}
}

Create Api Method:

    private static void CreateApis()
    {
        var classes = GetArrayOfClassInstances();


        foreach (KeyValuePair<int, Type> instance in classes)
        {
            Type apiType = typeof(Api<>).MakeGenericType(instance.Value);

            var api = Activator.CreateInstance(apiType, new[]{typeof(System.Net.EndPoint)});
        }
    }
Community
  • 1
  • 1
poppertech
  • 1,286
  • 2
  • 9
  • 17