【问题标题】:Roslyn get all object creations and its identifier nameRoslyn 获取所有对象创建及其标识符名称
【发布时间】:2017-06-07 08:39:09
【问题描述】:

我正在寻找一种解决方案来在方法中创建所有对象。我想出了以下解决方案来获取所有创作的列表:

var creations = MethodDeclaration.Body.DescendantNodes().OfType<ObjectCreationExpressionSyntax>();

但现在我正在寻找标识符名称(变量名称)。在调试时我发现,这个变量有这个信息——但是标识符属性是不可访问的。

creations.First().Parent.Parent.Identifier.ValueText;

如果有人能解决我的问题,我会非常高兴。

编辑

我正在尝试分析单元测试。例如:

[TestMethod]
public void WarningOverReferencedTest()
{
    var myVar = new MyObject();
    var myVar1 = new MyObject1();
    var myVar2 = new MyObject2();
    var myVar3 = new MyObject();
    var myVar4 = new MyObject3();
    Assert.AreEqual(true, myVar.someProperty);
    Assert.AreEqual(true, myVar3.someProperty2);
    Assert.AreEqual(true, myVar1.someProperty);
    Assert.AreEqual(true, myVar2.someProperty);
}

我想计算Assert.AreEqual 检查中使用的引用。所以上面的例子应该返回 3,因为 myVarmyVar3 来自同一类型,myVar4 没有在 Assert.AreEqual 检查中使用。

【问题讨论】:

  • 我更新了我的答案,马塞尔。
  • 到目前为止非常感谢。我如何从上面编辑的示例中计算这些引用?
  • 在我的回答中。您只需致电types.Count 即可获得计数。
  • 是的,我知道,但这不是 100% 正确的,因为我只有在断言中使用的那些类型。我现在会得到 4,但应该是 3。
  • 那么看Assert方法调用,从参数列表中收集ITypeSymbol-s,交叉引用两组。

标签: c# roslyn


【解决方案1】:

您需要将 creations.First().Parent.Parent 转换为具有 Identifier 属性的类型 - 在您的情况下,它很可能是 VariableDeclaratorSyntax - 然后您将能够访问它的 Identifier。这当然很危险,因为您可能会找到一个祖父母不同的ObjectCreationSyntax

看看这个例子:

List<Person> people = new List<Person>() {
      new Person("Jim"),
      new Person("Frank")
};

您将成功获得Identifierpeople ObjectCreation,但不是它的元素(因为它们根本没有变量名)。有很多角落案例需要解决,有很多可能的解决方案。

一个肮脏的解决方法是检查祖父母是否是一种VariableDeclarator,然后才施放它。也许如果你分享你想要完成的事情(在宏伟的计划中)我可以提供更好的建议。

编辑

如果我对您的理解正确,您想计算在方法中创建的不同类型的数量。 ObjectCreationExpressionSyntax 对象有一个 Type 属性,它显示正在创建的对象类型。这正是您所需要的,但是获取类型本身是 troublesome,但您可以查看名称如下:

HashSet<ITypeSymbol> types = new HashSet<ITypeSymbol>();

foreach (ObjectCreationExpressionSyntax node in creations)
{
    var typeSymbol = semanticModel.GetTypeInfo(node).Type;
    types.Add(typeSymbol);
}
int numberOfTypes = types.Count;

您不能只计算node.Type-s,因为它们是SyntaxNode-s,并且不会完全相同。但是它们的符号将是,并且使用HashSet 将确保您没有重复。如果使用RegisterSemanticModelAction,则可以从上下文中获取SemanticModel 对象。

【讨论】:

  • Type 只是源代码中出现的类型名称,而不是实际类型的名称。给定您的代码,stringStringSystem.String 将被视为不同的类型。然后我什至不谈论诸如using Text = String; 之类的别名。长话短说,您应该使用SemanticModel 并在ObjectCreationExpressionSyntax 上致电GetTypeInfo
  • @KrisVandermotten 确实,在我链接的问题中可以看到所有这些。我写的代码是为了他之前提供的例子(现在已经消失了)。但你是对的,我会尽快编辑它。
猜你喜欢
  • 2011-10-04
  • 2020-05-27
  • 2015-12-16
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 2014-03-27
相关资源
最近更新 更多