0
呼び出し中に具体的なタイプに特化した汎用メソッドの演算および/または構文ノードを取得することは可能ですか?したがって、下のサンプルではT
の代わりにstring
になりますか?Roslyn汎用メソッドの特殊化本体
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Semantics;
using System;
using System.Linq;
namespace so
{
internal class Walker : CSharpSyntaxWalker
{
public SemanticModel Model { get; set; }
public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
{
var operation = (IAssignmentExpression)Model.GetOperation(node);
if (operation.Value.Kind == OperationKind.InvocationExpression)
{
var invocation = (IInvocationExpression)operation.Value;
foreach (
var syntax in
invocation.TargetMethod.DeclaringSyntaxReferences.Select(
x => (MethodDeclarationSyntax)x.GetSyntax()))
{
var e = (TypeOfExpressionSyntax)syntax.ExpressionBody.Expression;
Console.WriteLine($"Generic type {invocation.TargetMethod.TypeParameters.First()} specialized with {invocation.TargetMethod.TypeArguments.First()}");
// How to get specialized body here? Currently it is just generic TypeParameters
var symbol = Model.GetSymbolInfo(e.Type).Symbol;
var typeofOperation = (ITypeOfExpression)Model.GetOperation(e);
Console.WriteLine($"{syntax.Identifier.Text} {symbol} {typeofOperation.TypeOperand}");
}
}
base.VisitAssignmentExpression(node);
}
}
internal static class Program
{
private static void Main()
{
var tree = CSharpSyntaxTree.ParseText(@"
public class Program
{
static Type TypeOf<T>() => typeof(T);
public static void Main()
{
Type t;
t = TypeOf<string>();
}
}");
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create(null, new[] { tree }, new[] { mscorlib });
var walker = new Walker { Model = compilation.GetSemanticModel(tree) };
walker.Visit(tree.GetRoot());
}
}
}
出力:
Generic type T specialized with string
TypeOf T T
そして、私は出力にTypeOf string string
を取得しようとしています。 githubの上
コード - https://github.com/isanych/so-39447605
はい、代入は呼び出し時に発生します。そのため、この情報を呼び出し式で取得しようとしています。手動で置換を実行するのは、多くの作業ですが、Roslynは特別な機能のためにILを生成していますが、私は実際に同じ作業をしたくありません:) – ISanych
これは.NETのジェネリックスの仕組みではありません。 ILには、ジェネリック関数のバージョンは1つしかなく、特殊な関数はありません。 – svick
あなたは正しいです、私は混乱しています。私は、特殊なクラスは異なるタイプであり、そこでもメソッドが異なると仮定しています。私はまだそれが当てはまると思いますが、これらの特殊なメソッドを作成するのはJITです。 ILは一度だけ生成されるので、必要なレベルの詳細ですべての操作を取得することが可能でなければなりません。ですから、SLaksが指摘しているように、まだ特殊な実装ではすべてのシンボルを解決する必要があります。私はこのトピックを研究する必要があります。 – ISanych