C#在我的项目解决方案中反射并查找类/属性的所有引用
我有一个名为Test的类,并在其他几个类中实例化了该类。是否有任何方法可以通过编程方式找到类“Fix”的所有引用。我知道我可以在VisualStudio中找到所有引用,但我想根据自己的需求以编程方式实现这一点。请帮忙 示例: Fix.csC#在我的项目解决方案中反射并查找类/属性的所有引用,c#,reflection,C#,Reflection,我有一个名为Test的类,并在其他几个类中实例化了该类。是否有任何方法可以通过编程方式找到类“Fix”的所有引用。我知道我可以在VisualStudio中找到所有引用,但我想根据自己的需求以编程方式实现这一点。请帮忙 示例: Fix.cs namespace Testing { public class Fix { public string fixName = "Name"; } } namespace Testing { public cla
namespace Testing
{
public class Fix
{
public string fixName = "Name";
}
}
namespace Testing
{
public class CodeFix
{
private string GetName()
{
Fix fix = new Fix();
return fix.fixName;
}
}
}
CodeFix.cs
namespace Testing
{
public class Fix
{
public string fixName = "Name";
}
}
namespace Testing
{
public class CodeFix
{
private string GetName()
{
Fix fix = new Fix();
return fix.fixName;
}
}
}
现在我想编写代码,在我的解决方案(名称空间测试)中查找对变量“fixName”
的所有引用。
对于类或变量,是否有任何方法可以通过编程实现这一点。我希望得到文件名和变量引用代码行的结果
例如:
Result
{
FileName="CodeFix.cs",
Line=return fix.fixName;
}
我应该自动执行下面的场景,我需要找到所有引用。
我应该不使用公共字段,因此当我找到像“fixName”这样的公共字段时,我应该将fixName从public更改为private,然后使用属性公开相同的字段
private string fixName;
public string FixName
{
get { return fixName; }
set { fixName = value; }
}
因此,我应该更改文件codeFix.cs-linereturn fix.fixName必须使用属性名return fix.FixName更改code>代码>
我有一个VSIX项目来修复代码冲突,我需要实现这个“自动修复”,以避免使用公共字段。有没有一种方法可以获取Visual Studio->查找所有引用数据?有一种方法可以使用Roslyn编写可以检查源代码的单元测试
对于测试项目,我使用的是xUnit
和Buildalyzer
(它本身引用了Microsoft.codelanalysis
包),因此这就是我的test.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Buildalyzer" Version="0.2.2" />
<PackageReference Include="Buildalyzer.Workspaces" Version="0.2.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
</Project>
netcoreapp2.0
现在只有一个单元测试:
public class UnitTest1
{
private readonly List<Document> _documents;
public UnitTest1()
{
var projPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "CodeFixDemoTests.csproj"));
AnalyzerManager manager = new AnalyzerManager();
ProjectAnalyzer analyzer = manager.GetProject(projPath);
AdhocWorkspace workspace = analyzer.GetWorkspace();
_documents = new List<Document>();
foreach (var projectId in workspace.CurrentSolution.ProjectIds)
{
var project = workspace.CurrentSolution.GetProject(projectId);
foreach (var documentId in project.DocumentIds)
{
var document = workspace.CurrentSolution.GetDocument(documentId);
if (document.SupportsSyntaxTree)
{
_documents.Add(document);
}
}
}
}
public string _myField;
[Fact]
public void NoPublicFields()
{
var classes = _documents.Select(doc => new { doc, classes = doc.GetSyntaxRootAsync().Result.DescendantNodes().OfType<ClassDeclarationSyntax>() })
.SelectMany(doc => doc.classes.Select(@class => new { @class, doc.doc }));
foreach (var classDeclaration in classes)
{
var classFields = classDeclaration.@class.DescendantNodes().OfType<FieldDeclarationSyntax>();
foreach (var field in classFields)
{
var fieldHasPrivateModifier = field.Modifiers.Any(modifier => modifier.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword));
if (!fieldHasPrivateModifier)
{
var errorMessage = $"Public field in class: \"{classDeclaration.@class.Identifier}\", File: {classDeclaration.doc.FilePath}";
Assert.True(false, errorMessage);
}
}
}
}
}
公共类UnitTest1
{
私人只读列表文件;
公共单元测试1()
{
var projPath=Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory()、“.”、“.”、“.”、“.codefixdemosts.csproj”);
AnalyzerManager=新AnalyzerManager();
ProjectAnalyzer=manager.GetProject(projPath);
AdhocWorkspace=analyzer.GetWorkspace();
_文件=新列表();
foreach(workspace.CurrentSolution.projectId中的var projectId)
{
var project=workspace.CurrentSolution.GetProject(projectId);
foreach(project.documentId中的var documentId)
{
var document=workspace.CurrentSolution.GetDocument(documentId);
if(document.SupportsSyntaxTree)
{
_文件。添加(文件);
}
}
}
}
公共字符串_myField;
[事实]
public void NoPublicFields()
{
var classes=_documents.Select(doc=>new{doc,classes=doc.GetSyntaxRootAsync().Result.degenantNodes().OfType()})
.SelectMany(doc=>doc.classes.Select(@class=>new{@class,doc.doc}));
foreach(类中的var类声明)
{
var classFields=classDeclaration.@class.degenantNodes().OfType();
foreach(类字段中的var字段)
{
var fieldhasprovatemodifier=field.Modifiers.Any(modifier=>modifier.IsKind(Microsoft.codealysis.CSharp.SyntaxKind.PrivateKeyword));
如果(!fieldHasPrivateModifier)
{
var errorMessage=$“类中的公共字段:\”{classDeclaration.@class.Identifier}\”,文件:{classDeclaration.doc.FilePath}”;
Assert.True(false,errorMessage);
}
}
}
}
}
它在运行时提供以下输出:
(发现的错误是测试类本身中的公共字符串\u myField;
)
只需确保为它提供指向您的csproj
文件的正确路径,您就可以开始了。如果你想把所有的错误分开,你可以重构它,用一个xUnitTheory
代替一个将所有类声明作为输入的Fact
。提供一些例子。并分享你提供的代码。嗨,斯托姆,用一个例子更新了我的问题。对我来说,这看起来像一个例子。上面的代码帮助不大,特别是因为里面没有Test
类。更重要的是,在程序运行时这样做的价值值得怀疑。无论是什么原因让你认为你想做到这一点,我怀疑有一个不同的,更好的方式去做。抱歉的困惑。现在我清楚地更新了我的问题。我有一个VSIX项目来修复代码冲突,我需要实现这个“自动修复”,以避免使用公共字段。有没有办法获取Visual Studio->查找所有引用数据?我建议您查看xunit.analyzers项目:用于构建这样一个功能。这不是我以前做过的,对不起,我以为你只是在问检测代码缺陷。