1

I'm trying to refactor some code but I'm not sure if I'm going about it the right way.

Below is a simplified switch where I'm creating an observable collection based on 2 parameters passed to a generic function. The first parameter is always an observable collection and the second is the type of the object stored in the observable collection:

switch (csvDataType)
{
  case CsvDataTypeEnum.Supplier:
    dataCollection = ConverterService.ConvertCsvDataToCollection
    <SupplierCollection, Supplier>(csvData);
    break;
  case CsvDataTypeEnum.Currency:
    dataCollection = ConverterService.ConvertCsvDataToCollection
    <CurrencyCollection, Currency>(csvData);
    break;
  case CsvDataTypeEnum.Custom:
    dataCollection = ConverterService.ConvertCsvDataToCollection
    <CustomDataObjectCollection, CustomDataObject>(csvData);
    break;
}

Based on the above, I was hoping to refactor the code to something similar to this:

ObjectInfo objectInfo = new ObjectInfo(csvDataType);

Type objectType = objectInfo.ObjectType;
Type collectionType = objectInfo.CollectionType;

dataCollection = ConverterService.ConvertCsvDataToCollection
<collectionType, objectType>(csvData);

My ConvertCsvDataToCollection generic function is defined as follows:

public static U ConvertCsvDataToCollection<U, T>(string csvData) 
where U : ObservableCollection<T>
{
....
}

I then use an implicit type using var:

var dataCollection = Activator.CreateInstance(collectionType);

and it create the correct observable collection of the required type but I can't get my generic function to take in the Type collectionType and objectType types as I was hoping for by calling it this way:

dataCollection = ConverterService.ConvertCsvDataToCollection
<collectionType, objectType>(csvData);

but I get the following error:

the 'type or namespace name 'collectionType' could not be found. Are you missing a directive or assembly reference'

for both the collectionType and the objectType parameters I'm passing to my generic function.

Is there a way to achieve this? I know this may have been previously asked in the past but I need clarification as the other similar issue I've read so far are still not addressing my problem, or I've totally missed their points. Sorry if that's the case!

Thanks.

Thierry
  • 6,142
  • 13
  • 66
  • 117
  • 2
    You can't do that. You need reflection. – SLaks Oct 22 '15 at 16:02
  • Or Expression Trees. Generic type parameters have to be set at compile time. You can somewhat get around it without reflection or expression trees by passing a `Type` as part of the parameter list, but at that point you're not using generics anymore. – Bradford Dillon Oct 22 '15 at 16:05
  • Thanks for the feedback and apologies for being a re-post but I originally struggle understanding the reflection article I had found including the one mentioned above. Once the penny dropped, the rest was easy and it's working great, but most of the samples were explaining a method with a single parameter, so I might post my own answer on the other post and it will hopefully help others. – Thierry Oct 22 '15 at 22:45

0 Answers0