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);
}
}