【问题标题】:Substituting (Dictionary<string, ITypeSymbol> typeParameterValues) into ITypeSymbol in all cases在所有情况下都将 (Dictionary<string, ITypeSymbol> typeParameterValues) 替换为 ITypeSymbol
【发布时间】:2021-09-14 07:58:30
【问题描述】:

我有一个类型参数值的字典:

ImmutableDictionary<string, ITypeSymbol> typeParameterValues;

如何使用 ITypeSymbol 替换这些类型参数:

例如。 List&lt;T&gt; -> List&lt;string&gt;(如果 T 是字符串)

例如。 Dictionary&lt;K, V&gt;.ValueCollection -> Dictionary&lt;string, int&gt;.ValueCollection(如果 K 是字符串,V 是整数)

到目前为止,我已经能够使用以下代码使第一个示例工作:

static ITypeSymbol SubstituteGenericArgs (ITypeSymbol type) => type switch {
    ITypeParameterSymbol tps => typeParameterValues[tps.Name]
    INamedTypeSymbol nts when nts.IsGeneric => nts.ConstructedFrom.Construct(
        nts.TypeParameters.Select(SubstituteGenericArgs).ToArray()
    ),
    INamedTypeSymbol ngts when !ngts.IsGeneric => ngts
};

我知道我可以做到nts.ContainingType,但问题是一旦我将正确的类型参数替换为包含类型,就无法使用我找到的新包含类型来获取原始类型。

【问题讨论】:

  • 您能否格式化您的代码以使其更具可读性?
  • 我尽力了。_
  • 我的编辑有帮助吗?如果没有,请拒绝/恢复它们。
  • 所以你问的是,当nts.ContainingType.IsGeneric 如何判断SubstituteGenericArgs(nts.ContainingType).GetMembers(nts.Name) 中的哪一个与nts 是同一成员?也许通过比较.OriginalDefinition

标签: c# roslyn


【解决方案1】:

这是我想出来的:

public record GenericContext (Dictionary<string, ITypeSymbol> typeParameterValues)
{
    public ITypeSymbol SubstituteGenericArgs (ITypeSymbol type) => type switch
    {
        INamedTypeSymbol nts when nts.ContainingType is {} ct && ct.IsGenericType => SimpleSubstituteGenericArgs(
            SubstituteGenericArgs(ct).GetMembers().OfType<INamedTypeSymbol>().Single(
                gv => gv.OriginalDefinition == nts.OriginalDefinition
            )
        ),
        _ => SimpleSubstituteGenericArgs(type)
    };

    public ITypeSymbol SimpleSubstituteGenericArgs(ITypeSymbol type) => type switch
    {
        ITypeParameterSymbol tps => typeParameterValues[tps.Name],
        INamedTypeSymbol nts when nts.TypeArguments.Length == 0 => nts,
        INamedTypeSymbol nts when nts.TypeArguments.Length >  0 => nts.ConstructedFrom.Construct(
            nts.TypeArguments.Select(SubstituteGenericArgs).ToArray()
        )
    };
}

谢谢@Jeremy Lakeman

请看这里:https://dotnetfiddle.net/AIlKBw

如果您有任何改进意见,请告诉我。我认为这将是一个内置功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    相关资源
    最近更新 更多