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

如何在Runtime动态创建匿名类型并填充legs数组?

运行时创建含动态元素数量的匿名类型

针对你的需求,匿名类型的结构(字段名、类型)是固定的,仅legs数组的元素数量需要在运行时动态生成,这里提供两种实用方案:

方法一:LINQ+匿名类型推断(最简洁高效)

匿名类型的类型信息由编译器在编译时推断,我们可以先基于固定字段完成类型映射,再通过LINQ将运行时数据源(List<DataRow>或自定义结构体集合)转换成对应匿名类型的数组,最后组装外层匿名类型。

针对自定义结构体数据源

假设你有如下结构体定义:

public struct LegInfo
{
    public string InstrumentType;
    public string Symbol;
    public string Quantity;
    public string Action;
}

转换代码示例:

// 模拟运行时获取的结构体列表
List<LegInfo> legSource = new List<LegInfo>
{
    new LegInfo { InstrumentType = "Equity Option", Symbol = "SPY   221021C00422000", Quantity = "1", Action = "Buy to Open" },
    new LegInfo { InstrumentType = "Equity Option", Symbol = "SPY   221021C00420000", Quantity = "1", Action = "Sell to Open" }
};

// 转换为匿名类型数组
var legs = legSource.Select(l => new 
{
    instrumenttype = l.InstrumentType,
    symbol = l.Symbol,
    quantity = l.Quantity,
    action = l.Action
}).ToArray();

// 组装外层匿名类型
var orderFields = new { legs = legs };

针对List数据源

如果数据源是数据库查询返回的List<DataRow>,只需调整字段映射逻辑:

List<DataRow> rowSource = ...; // 从DataTable获取的行集合

var legs = rowSource.Select(row => new 
{
    instrumenttype = row["instrumenttype"].ToString(),
    symbol = row["symbol"].ToString(),
    quantity = row["quantity"].ToString(),
    action = row["action"].ToString()
}).ToArray();

var orderFields = new { legs = legs };

方法二:反射创建匿名类型(仅复杂场景备用)

如果你的场景中匿名类型的字段无法提前确定(但你的需求里字段是固定的,此方法非必要),可以通过反射动态生成匿名类型,但代码繁琐且性能较差,示例如下:

using System.Reflection;
using System.Reflection.Emit;

// 工具类:动态生成匿名类型
public static class AnonymousTypeCreator
{
    public static Type CreateAnonymousType(IDictionary<string, Type> fieldTypes)
    {
        var assemblyName = new AssemblyName("DynamicAnonymousTypes");
        var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        var moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
        
        // 匿名类型默认是密封类,带CompilerGenerated特性
        var typeBuilder = moduleBuilder.DefineType($"<>f__AnonymousType{Guid.NewGuid():N}", 
            TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class);
        
        // 添加字段和属性
        foreach (var field in fieldTypes)
        {
            var fieldBuilder = typeBuilder.DefineField($"<{field.Key}>i__Field", field.Value, FieldAttributes.Private | FieldAttributes.InitOnly);
            var propertyBuilder = typeBuilder.DefineProperty(field.Key, PropertyAttributes.None, field.Value, null);
            
            // 属性get方法实现
            var getMethod = typeBuilder.DefineMethod($"get_{field.Key}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, field.Value, Type.EmptyTypes);
            var il = getMethod.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, fieldBuilder);
            il.Emit(OpCodes.Ret);
            propertyBuilder.SetGetMethod(getMethod);
        }
        
        // 生成构造函数
        var ctorParams = fieldTypes.Values.ToArray();
        var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams);
        il = ctorBuilder.GetILGenerator();
        for (int i = 0; i < ctorParams.Length; i++)
        {
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg, i + 1);
            il.Emit(OpCodes.Stfld, typeBuilder.GetField($"<{fieldTypes.Keys.ElementAt(i)}>i__Field"));
        }
        il.Emit(OpCodes.Ret);
        
        return typeBuilder.CreateType();
    }
}

// 使用示例
var legFieldTypes = new Dictionary<string, Type>
{
    { "instrumenttype", typeof(string) },
    { "symbol", typeof(string) },
    { "quantity", typeof(string) },
    { "action", typeof(string) }
};
Type legType = AnonymousTypeCreator.CreateAnonymousType(legFieldTypes);

// 创建单个leg实例
object legInstance = Activator.CreateInstance(legType, "Equity Option", "SPY   221021C00422000", "1", "Buy to Open");

// 创建数组并填充
Array legsArray = Array.CreateInstance(legType, 2);
legsArray.SetValue(legInstance, 0);
// 填充第二个元素...

// 创建外层匿名类型
var outerFieldTypes = new Dictionary<string, Type> { { "legs", legsArray.GetType() } };
Type outerType = AnonymousTypeCreator.CreateAnonymousType(outerFieldTypes);
var orderFields = Activator.CreateInstance(outerType, legsArray);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 08:15:29