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

为Wrapper结构体实现集合初始化器并避免IEnumerator<T>装箱

问题解决方案

一、解决枚举器装箱问题

你的代码中,强类型GetEnumerator返回了接口类型IEnumerator<KeyValuePair<string, string>>,而Dictionary<TKey,TValue>.Enumerator是值类型,返回接口时会触发装箱。解决核心是让Wrapper直接返回值类型枚举器,同时显式实现接口方法:

public readonly struct Wrapper : IEnumerable<KeyValuePair<string, string>>
{
    public Dictionary<string, string> Instance { get; }

    public Wrapper()
    {
        Instance = new Dictionary<string, string>();
    }

    public void Add(string key, string value)
    {
        Instance.Add(key, value);
    }

    // 直接返回值类型枚举器,避免foreach场景下的装箱
    public Dictionary<string, string>.Enumerator GetEnumerator()
    {
        return Instance.GetEnumerator();
    }

    // 显式实现泛型接口的GetEnumerator,仅在强制转换为接口时触发装箱(极少场景)
    IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
    {
        return GetEnumerator();
    }

    // 显式实现非泛型接口的GetEnumerator
    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<KeyValuePair<string, string>>)this).GetEnumerator();
    }
}

这样修改后:

  • 使用foreach遍历Wrapper实例时,编译器会优先调用返回值类型的GetEnumerator方法,完全避免装箱。
  • 只有将Wrapper强制转换为IEnumerable<KeyValuePair<string, string>>或IEnumerable接口后调用枚举器,才会触发装箱,这类场景通常很少见。

二、集合初始化器的使用

你的代码已经包含Add(string key, string value)方法,且默认构造会初始化空字典,因此可以直接使用集合初始化语法:

var wrapper = new Wrapper
{
    {"Key1", "Value1"},
    {"Key2", "Value2"}
};

编译器会自动生成“调用默认构造 → 依次调用Add方法”的代码,满足你的需求。

注意:Wrapper是readonly结构体,但Instance是引用类型,修改Instance的内容(如调用Add)是允许的,readonly仅限制Instance字段本身的引用不能被重新赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:35:05