获取对象类型并在泛型方法调用中使用

时间:2016-07-06 19:20:42

标签: c# generics

我有一个通用的方法来处理从Quickbooks中导入各种对象类型。

public ActionConfirmation<int> Import<TEntity>(List<TEntity> lstEntityModifiedSinceLastSync, FinancialsSyncJobQueue currentJobQEntry, FinancialsSyncSession session, 
    FinancialsIntegrationContext financialsIntegrationContext) 
    where TEntity : class, IEntity, IAuditStamps, IFinancials, new()

今天我使用switch语句以正确的类型调用上面的泛型方法:

switch (enumDataElement)
{
    case DataElement.Account:
        {
            //Parse QB query response and convert to Stratus Chart of Accounts object list
            var lstAccountsModifiedSinceLastSync = QuickbooksChartOfAccounts.ParseQueryResponse(response, session);

            importResult = importService.Import<FinancialsChartOfAccount>(lstAccountsModifiedSinceLastSync, 
                currentJobQEntry, session, financialsIntegrationContext);

            break;
        }
    case DataElement.Item:
        {
            var lstItemsModifiedSinceLastSync = QuickbooksItem.ParseQueryResponse(response, session);

            importResult = importService.Import<Item>(lstItemsModifiedSinceLastSync, 
                currentJobQEntry, session, financialsIntegrationContext);

            break;
        }
        etc...
}

我想稍微清理一下,将switchService.Import调用从switch语句中取出并放在最后并执行以下操作:

Type entityType = lstItemsModifiedSinceLastSync.FirstOrDefault().GetType();
importResult = importService.Import<entityType>(lstItemsModifiedSinceLastSync, 
    currentJobQEntry, session, financialsIntegrationContext);

但我似乎无法让它发挥作用。错误是:The type or namespace could not be found...

1 个答案:

答案 0 :(得分:1)

这不会起作用,因为类型参数是类型的实际名称,由编译器在编译时解析。它需要一个类型的名称,但是你要给它一个变量的名称。

Type entityType = lstItemsModifiedSinceLastSync.FirstOrDefault().GetType();
importResult = importService.Import<entityType>(lstItemsModifiedSinceLastSync, 
    currentJobQEntry, session, financialsIntegrationContext);

可以使用在运行时确定的类型参数but you have to use reflection来调用泛型方法。对于你的情况,这样的事情(未经测试):

//  Get the entity type by reflection too, so we don't have to worry about
//  crashing on an empty list. 
Type entityType = lstItemsModifiedSinceLastSync.GetType().GenericTypeArguments.First();

MethodInfo method = importService.GetType().GetMethod("Import");
MethodInfo generic = method.MakeGenericMethod(entityType);

generic.Invoke(importService, new object[] { 
        lstItemsModifiedSinceLastSync, 
        currentJobQEntry, 
        session, 
        financialsIntegrationContext
    });

您是否认为这比您已经拥有的更难或更丑。如果Import有重载,那么您必须翻找MethodInfo个对象列表才能找到正确的对象。

顺便说一句,您还可以使用lstItemsModifiedSinceLastSync上的类型信息来获取类型参数,而不是依赖列表中的项目。如果没有,FirstOrDefault()将返回null,该行将抛出异常。