Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向var类型的变量添加新项-在一个变量中包含构造函数和方法声明_C#_.net_Roslyn - Fatal编程技术网

C# 向var类型的变量添加新项-在一个变量中包含构造函数和方法声明

C# 向var类型的变量添加新项-在一个变量中包含构造函数和方法声明,c#,.net,roslyn,C#,.net,Roslyn,我有以下代码: var allclasses = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var memcls in allclasses) { if (memcls != null) { var methodDeclarations = memcls.DescendantNodes().OfType<MethodDeclaration

我有以下代码:

var allclasses = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>();
foreach (var memcls in allclasses)
{
    if (memcls != null)
    {
        var methodDeclarations = memcls.DescendantNodes().OfType<MethodDeclarationSyntax>();
        foreach (var memmeth in methodDeclarations)
        {
            var paramDeclaratons = memmeth.ParameterList.Parameters;

但是,在代码后面访问ParameterList和Identifier属性时再次出现错误。

如@Chris所述,如果共享基类没有您想要的适当属性,您可能应该使用两个单独的列表

但是,如果您确实希望使用单个列表,则以下操作将起作用:

var methodDeclarations =
    tree.GetRoot()
        .DescendantNodes()
        .Where(c => c is MethodDeclarationSyntax || c is ConstructorDeclarationSyntax)
        .Cast<dynamic>();

foreach (var memmeth in methodDeclarations)
{
    // Run-time checking so no syntax error
    Console.WriteLine(memmeth.Identifier);
}
var方法声明=
tree.GetRoot()
.DegeneratNodes()的
.其中(c=>c是MethodDeclarationSyntax | | c是ConstructorDeclarationSyntax)
.Cast();
foreach(methodDeclarations中的var memmeth)
{
//运行时检查,因此没有语法错误
Console.WriteLine(memmeth.Identifier);
}
但是,请注意,由于需要反射,这会降低性能,并且还会丢失编译器通常提供的所有良好静态语法检查。

您可以使用
列表,如下所示:

var methods = new List<BaseMethodDeclarationSyntax>();
methods.AddRange(memcls.DescendantNodes().OfType<MethodDeclarationSyntax>());
methods.AddRange(memcls.DescendantNodes().OfType<ConstructorDeclarationSyntax>());
foreach (var method in methods)
{
    var identifier = IdentifierVisitor.Instance.Visit(method);

    // for example:
    Console.WriteLine(identifier.Text);
}
拥有该类后,可以按如下方式获取标识符:

var methods = new List<BaseMethodDeclarationSyntax>();
methods.AddRange(memcls.DescendantNodes().OfType<MethodDeclarationSyntax>());
methods.AddRange(memcls.DescendantNodes().OfType<ConstructorDeclarationSyntax>());
foreach (var method in methods)
{
    var identifier = IdentifierVisitor.Instance.Visit(method);

    // for example:
    Console.WriteLine(identifier.Text);
}
这将适用于常规方法、构造函数和析构函数。 在某种程度上,它也适用于运算符和转换运算符,只是这些运算符将返回默认标记。所以你可以这样做:

var methods = memcls
    .DescendantNodes()
    .OfType<BaseMethodDeclarationSyntax>()
    .ToList();

foreach (var method in methods)
{
    var identifier = IdentifierVisitor.Instance.Visit(method);

    if (!identifier.IsKind(SyntaxKind.None))
    {
        Console.WriteLine(identifier.Text);
    }
}
var方法=memcls
.DegeneratNodes()的
第()类
.ToList();
foreach(方法中的var方法)
{
var identifier=IdentifierVisitor.Instance.Visit(方法);
如果(!identifier.IsKind(SyntaxKind.None))
{
Console.WriteLine(identifier.Text);
}
}

最后一件事:调用.degentNodes()将为您提供整个ClassDeclarationSyntax树中的每个节点。您可能应该改用.Members。这不会给您提供嵌套类中的方法(尽管如果需要,您可以很容易地递归获得这些方法),但它会更有效。

您需要告诉我们更多有关这些类的信息。例如,
MethodDeclarationSyntax
ConstructorDeclarationSyntax
的公共基类型是什么?如果您将methodDeclarations设置为该类型的列表,那么您应该能够将它们添加到相同的列表中。当然,如果基类没有属性
ParameterList
,那么访问该属性的尝试将失败。在这种情况下,您希望发生什么?这些是Microsoft.CodeAnalysis.CSharp.Syntax命名空间中的Roslyn类型,如下所述:MethodDeclarationSyntax和ConstructorDeclarationSyntax都有ParameterList和Identifier属性,但它们的基类BaseMethodDeclarationSyntax,例如,没有标识符属性您是否尝试了
List methodDeclarations=…
,因为这似乎是基本类型?抱怨什么?它给出了什么错误?如果基类没有您想要的属性,那么您将不得不单独处理它们,因为您需要将它们转换为更特定的类型来调用属性,此时似乎不值得将它们放在同一个列表中。
var methods = memcls
    .DescendantNodes()
    .OfType<BaseMethodDeclarationSyntax>()
    .ToList();

foreach (var method in methods)
{
    var identifier = IdentifierVisitor.Instance.Visit(method);

    if (!identifier.IsKind(SyntaxKind.None))
    {
        Console.WriteLine(identifier.Text);
    }
}