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

如何将Object转换为泛型List<T>并作为Func输入参数传入?

问题描述

我定义了一套Operator类体系,其中SingleOperand<T,O>包含Func<T,O>类型的Function成员。当T是int、float或string这类简单类型时,能直接把object转换为对应类型后调用Function;但当T是泛型List类型时,不知道如何将输入的object(比如List<int>或List<object>)转换为目标List<TElement>类型(比如List<float>)。目前只有完全匹配的测试用例能通过,需要实现可转换列表的类型适配功能。

原实现代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace GameToolkit.Operator
{
    public abstract class IOperator
    {
        public abstract Type OutputType { get; }
        public abstract Type[] GetInputTypes();
        public abstract object GetValue(object a);
        public ValueToken GetValues(object a)
        {
            var v = GetValue(a);
            return new ValueToken() { Type = v.GetType(), Value = v };
        }
    }
    public class SingleOperand<T, O> : IOperator
    {
        public Func<T, O> Function { get; set; }
        public SingleOperand()
        {
        }
        public SingleOperand(Func<T, O> function)
        {
            Function = function;
        }
        public override object GetValue(object a)
        {
            if (Function == null)
                return default(T);
            if (a.GetType().IsGenericType)
            {
                ///SOME CODE HERE!!!
            }
            else
            return Function((T)a);
        }
        public override Type OutputType => typeof(O);

        public override Type[] GetInputTypes()
        {
            return new[] { typeof(T) };
        }
    }
}

测试场景

[Test]
public void UTValueExpressions1()
{
    var a = new SingleOperand<List<float>, bool>((b)=>{return b.Count > 0;});
    a.GetValue(new List<float>{1,2});
}
[Test]
public void UTValueExpressions2()
{
    var a = new SingleOperand<List<float>, bool>((b)=>{return b.Count > 0;});
    a.GetValue(new List<int>{1,2});
}
[Test]
public void UTValueExpressions3()
{
    var a = new SingleOperand<List<float>, bool>((b)=>{return b.Count > 0;});
    a.GetValue(new List<object>{1,2});
}

目前仅UTValueExpressions1能通过,需要让后两个测试也正常执行,实现将List<int>/List<object>转换为List<float>的功能(元素可转换时)。


解决方案

修改SingleOperand<T,O>的GetValue方法,通过反射识别目标List的元素类型,遍历输入集合的每个元素尝试转换,最终构建目标类型的List实例:

public override object GetValue(object a)
{
    if (Function == null)
        return default(T);
    
    // 优先尝试直接转换,适配简单类型和完全匹配的List场景
    try
    {
        return Function((T)a);
    }
    catch (InvalidCastException)
    {
        var targetType = typeof(T);
        // 检查目标类型是否为List<>
        if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(List<>))
        {
            var targetElementType = targetType.GetGenericArguments()[0];
            // 检查输入对象是否为可枚举类型
            if (a is IEnumerable inputEnumerable)
            {
                // 创建目标类型的List实例
                var targetList = Activator.CreateInstance(targetType) as IList;
                foreach (var item in inputEnumerable)
                {
                    try
                    {
                        // 尝试将元素转换为目标元素类型
                        var convertedItem = Convert.ChangeType(item, targetElementType);
                        targetList?.Add(convertedItem);
                    }
                    catch (InvalidCastException)
                    {
                        throw new InvalidCastException($"无法将元素 {item} 转换为类型 {targetElementType}");
                    }
                }
                // 将转换后的List传入Function执行
                return Function((T)(object)targetList);
            }
        }
        // 其他无法处理的转换情况,抛出原异常
        throw;
    }
}

代码说明

  • 优先直接转换:先尝试强转,兼容原有简单类型和完全匹配的List场景,减少反射开销。
  • 反射识别List类型:直接转换失败时,检查目标类型T是否为List<>,提取其元素类型。
  • 元素逐个转换:将输入的可枚举对象逐个元素转换为目标类型,构建目标List实例。
  • 异常处理:元素转换失败时抛出明确异常,也可根据业务需求改为跳过无效元素。

测试验证

修改后三个测试用例均可正常通过:

  • UTValueExpressions1:类型完全匹配,直接执行。
  • UTValueExpressions2:List<int>的每个元素转换为float,构建List<float>后传入Function。
  • UTValueExpressions3:List<object>中的整数元素转换为float,构建List<float>后传入Function。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:55