You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# 同逻辑任务处理方法如何支持返回不同类型结果

解决方案

核心思路是把通用流程和可变逻辑拆分:任务执行、异常捕获、结果合并的固定逻辑留在通用方法里,不同类型的实例创建、属性赋值这类可变逻辑通过委托交给调用方实现,既不需要修改现有三个类型的定义,也完美适配参数化构造函数的要求,全程编译期类型检查,没有反射的性能和稳定性问题。
不要尝试用new()泛型约束,该约束仅支持无参构造函数,无法适配Type1、Type2的参数化构造要求;也不要用反射动态调用构造函数,既存在性能损耗,构造参数变更时也无法在编译期捕获错误,容易引发运行时异常。

通用泛型方法实现

private async Task<T> GetPoliciesFromTasks<T>(
    IList<Task> taskList,
    Func<T> defaultInstanceFactory,
    Action<T, AppsPermissionSettings> permissionPolicySetter)
{
    TeamsAppPermissionPolicy backendPermissionDoc = new TeamsAppPermissionPolicy();
    try
    {
        await Task.WhenAll(taskList);
    }
    catch (Exception ex)
    {
        foreach (Task faultedTask in taskList.Where(t => t.IsFaulted))
        {
            Exception innerEx = faultedTask.Exception?.InnerException;
            DiagnosticsContext.Logger.LogError($"Task {faultedTask} execution failed, exception: {ex}");
        }
    }

    // 读取主任务结果,失败时通过传入的工厂创建默认实例
    T result = taskList[0].IsFaulted
        ? defaultInstanceFactory()
        : ((Task<T>)taskList[0]).Result;

    // 读取权限任务结果
    if (taskList.Count > 1)
    {
        backendPermissionDoc = taskList[1].IsFaulted
            ? new TeamsAppPermissionPolicy()
            : ((Task<TeamsAppPermissionPolicy>)taskList[1]).Result;
    }

    // 合并权限结果,通过传入的委托赋值到对应属性
    AppsPermissionSettings mergedPolicy = backendPermissionDoc
        .ToMTTeamsAppPermissionPolicy()
        .ToMTPolicyDocument();
    permissionPolicySetter(result, mergedPolicy);

    return result;
}

各场景调用示例

1. 返回AcmsSettings类型

任务构造逻辑和原有逻辑完全一致,调用时传入对应工厂和赋值逻辑即可:

var taskList = new List<Task>
{
    _myProxy.GetMySettings(/* 原有业务参数 */)
};
if (isTenantResolutionModelCustom)
{
    taskList.Add(GetDocFromCacheOrBackendAsync(null, userId));
}

AcmsSettings settingsResult = await GetPoliciesFromTasks(
    taskList,
    defaultInstanceFactory: () => new AcmsSettings(),
    permissionPolicySetter: (instance, policy) => instance.AppsPermissionPolicy = policy
);

2. 返回Type1类型

提前准备好Type1构造所需的参数,在工厂委托中传入即可,通用方法完全不需要感知构造逻辑:

var taskList = new List<Task>
{
    _myProxy.GetType1Settings(tenantId, userPoliciesToFetch) // 该方法返回Task<Type1>
};
if (isTenantResolutionModelCustom)
{
    taskList.Add(GetDocFromCacheOrBackendAsync(null, userId));
}

// 提前准备构造参数
UserSettings userSettings = GetCurrentUserSettings();
Permissions basePermissions = GetUserBasePermissions();

Type1 type1Result = await GetPoliciesFromTasks(
    taskList,
    defaultInstanceFactory: () => new Type1(userSettings, basePermissions),
    permissionPolicySetter: (instance, policy) => instance.AppsPermissionPolicy = policy
);

3. 返回Type2类型

调用逻辑和Type1完全一致,传入对应构造参数即可:

var taskList = new List<Task>
{
    _myProxy.GetType2Settings(/* Type2对应方法的业务参数 */) // 该方法返回Task<Type2>
};
if (isTenantResolutionModelCustom)
{
    taskList.Add(GetDocFromCacheOrBackendAsync(null, userId));
}

// 提前准备构造参数
Properties type2Props = GetType2Properties();
Permissions basePermissions = GetUserBasePermissions();

Type2 type2Result = await GetPoliciesFromTasks(
    taskList,
    defaultInstanceFactory: () => new Type2(type2Props, basePermissions),
    permissionPolicySetter: (instance, policy) => instance.AppsPermissionPolicy = policy
);

可选简化方案

如果可以修改现有三个类型的定义,可以给所有带AppsPermissionPolicy属性的类型统一加一个公共接口,省掉每次传permissionPolicySetter的步骤:

// 定义公共接口
public interface IPermissionPolicyContainer
{
    AppsPermissionSettings AppsPermissionPolicy { get; set; }
}

// 三个类型分别实现该接口,不需要修改原有类的任何业务代码
public class AcmsSettings : IPermissionPolicyContainer { /* 原有代码保持不变 */ }
public class Type1 : IPermissionPolicyContainer { /* 原有代码保持不变 */ }
public class Type2 : IPermissionPolicyContainer { /* 原有代码保持不变 */ }

给泛型方法加接口约束后,就可以去掉赋值委托参数,方法内部直接完成属性赋值:

private async Task<T> GetPoliciesFromTasks<T>(
    IList<Task> taskList,
    Func<T> defaultInstanceFactory) where T : IPermissionPolicyContainer
{
    // 其余逻辑和之前一致,赋值时直接操作接口属性即可
    result.AppsPermissionPolicy = mergedPolicy;
    return result;
}

后续如果新增同结构的类型,只要实现这个接口就能直接复用方法,不需要调整通用逻辑。


内容的提问来源于stack exchange,提问作者Programmerzzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:36:16