在所有情况下将 (Dictionary<string, ITypeSymbol> typeParameterValues) 替换为 ITypeSymbol
Substituting (Dictionary<string, ITypeSymbol> typeParameterValues) into ITypeSymbol in all cases
我有一个类型参数值的字典:
ImmutableDictionary<string, ITypeSymbol> typeParameterValues;
我如何使用 ITypeSymbol 替换这些类型参数:
例如。 List<T>
-> List<string>
(如果 T 是字符串)
例如。 Dictionary<K, V>.ValueCollection
-> Dictionary<string, int>.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
但问题是一旦我将正确的类型参数替换为包含类型,就无法使用我找到的新包含类型来获取原始类型.
这是我想到的:
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()
)
};
}
看这里:https://dotnetfiddle.net/AIlKBw
如果您有任何改进,请告诉我。我认为这将是一个内置功能。
我有一个类型参数值的字典:
ImmutableDictionary<string, ITypeSymbol> typeParameterValues;
我如何使用 ITypeSymbol 替换这些类型参数:
例如。 List<T>
-> List<string>
(如果 T 是字符串)
例如。 Dictionary<K, V>.ValueCollection
-> Dictionary<string, int>.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
但问题是一旦我将正确的类型参数替换为包含类型,就无法使用我找到的新包含类型来获取原始类型.
这是我想到的:
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()
)
};
}
看这里:https://dotnetfiddle.net/AIlKBw
如果您有任何改进,请告诉我。我认为这将是一个内置功能。