Visual Studio:查找特定类型的所有引用

我将一个(C#)结构转换为一个类,并且需要通过该类型的所有用途来确保前面的隐式复制和现在引用行为没有不良影响。

有没有办法找到所有的引用,这种特定类型的使用/涉及?

我尝试过在类型上Find all References ,并获取类型名称的所有位置,这是一个好的开始。

但是,我没有得到这种类型的实例返回和修改的位置。 具体来说,我使用var将返回值赋值给隐式类型变量,或者将所有赋值赋予先前定义的变量。

有什么功能或技巧我可以使用? 我想,这种结构到类的转换经常发生。 也许你有一些建议如何找到所有可能的问题?


您可以手动重命名类...每个错误都是使用它的地方。 但我认为Visual Studio会在发生一定数量的错误后停止。

你可以标记为[Obsolete]类,它的所有属性及其所有方法。 那么你每次使用它们都会有警告。

请注意[Obsolete] “技巧”有一些限制:

[Obsolete]
public class MyClass
{
}

public static void Test1(MyClass test2) // This line has a warning
{
    var y = test2; // ***This line doesn't have a warning***
    MyClass z = test2; // This line has a warning
}

所以它与Find all References相同...

基于Visual Studio的FxCop /代码分析的另一个解决方案:

这是一个自定义规则,基于http://blogs.msdn.com/b/codeanalysis/archive/2010/03/26/how-to-write-custom-static-code-analysis-rules-and -integrate了他们,成为视觉工作室,2010.aspx

程序集的默认名称空间(可以在属性中设置)必须是MyCustomFxCopRules 。 该平台的目标是x86。

using Microsoft.FxCop.Sdk;

namespace MyCustomFxCopRules
{
    public class StructAssignmentFinder : BaseIntrospectionRule
    {
        public StructAssignmentFinder()
            : base("StructAssignmentFinder", "MyCustomFxCopRules.RuleMetadata", typeof(StructAssignmentFinder).Assembly)
        {
            var ms = new MyStruct();
            var tt = ms;
        }

        public override TargetVisibilities TargetVisibility
        {
            get
            {
                return TargetVisibilities.All;
            }
        }

        public override ProblemCollection Check(ModuleNode module)
        {
            Visit(module);
            return Problems;
        }

public override void VisitAssignmentStatement(AssignmentStatement assignment)
{
    // You could even use FullName
    if ((assignment.Source != null && assignment.Source.Type != null && assignment.Source.Type.Name.Name == "MyStruct") ||
        (assignment.Target != null && assignment.Target.Type != null && assignment.Target.Type.Name.Name == "MyStruct"))
    {
        Problem problem = new Problem(GetNamedResolution("Struct", assignment.Target.Type.Name.Name), assignment);
        Problems.Add(problem);
    }

    base.VisitAssignmentStatement(assignment);
}

public override void VisitConstruct(Construct construct)
{
    Method targetMethod = (Method)((MemberBinding)construct.Constructor).BoundMember;

    if (targetMethod.Parameters.Any(x => x.Type.Name.Name == "MyStruct"))
    {
        Problem problem = new Problem(GetNamedResolution("ParameterType", "MyStruct", targetMethod.Name.Name), construct);
        Problems.Add(problem);
    }

    base.VisitConstruct(construct);
}

public override void VisitMethodCall(MethodCall call)
{
    Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;

    if (targetMethod.ReturnType.Name.Name == "MyStruct")
    {
        Problem problem = new Problem(GetNamedResolution("ReturnType", targetMethod.ReturnType.Name.Name, targetMethod.Name.Name), call);
        Problems.Add(problem);
    }

    if (targetMethod.Parameters.Any(x => x.Type.Name.Name == "MyStruct"))
    {
        Problem problem = new Problem(GetNamedResolution("ParameterType", "MyStruct", targetMethod.Name.Name), call);
        Problems.Add(problem);
    }

    base.VisitMethodCall(call);
}

RuleMetadata.xml (它必须是嵌入式资源)

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Rules about Structs">
  <Rule TypeName="StructAssignmentRule" Category="MyRules" CheckId="CR1000">
    <Name>Struct Assignment Finder</Name>
    <Description>Struct Assignment Finder</Description>
    <Url></Url>
    <Resolution Name="Struct">There is an assignment of struct '{0}'.</Resolution>
    <Resolution Name="ReturnType">'{0}' is the return type for a call to '{1}'.</Resolution>
    <Resolution Name="ParameterType">'{0}' is a parameter type for a call to '{1}'.</Resolution>
    <Email></Email>
    <MessageLevel Certainty="100">Warning</MessageLevel>
    <FixCategories>NonBreaking</FixCategories>
    <Owner></Owner>
  </Rule>
</Rules>

基于此,可以很容易地为其他角落案例添加其他规则,我肯定会忘记:-)

我正在使用的测试文件:

public struct MyStruct
{

}

class Test
{
    public Test()
    {
        var ms = new MyStruct();
        var ms2 = ms;

        ms3 = ms;
        ms = ms3;

        ms4 = ms;
        ms = ms4;

        ms4 = ms4;

        new MyObject(default(MyStruct));
    }

    public MyStruct ms3;
    public MyStruct ms4 { get; set; }
}

public class MyObject
{
    public MyObject(MyStruct par1)
    {

    }
}

请注意,调试规则非常棘手...使用FxCopCmd.exe进行调试非常容易,但是直接由Visual Studio调用时调试是不可能的(我认为,不确定)。


答案和评论让我得到了满意的解决方案,可能有助于其他人,所以我想我会发布它。

问题不在于寻找所有用途,而仅仅是“有问题”的问题,即写入公众成员的问题。 正如本答案中的建议,我只想找到写入权限,而不是找到对成员的所有引用。 因此,我使用了类似于此答案中所述的重写策略,并使所有成员都只写,所以编译器只会抱怨危险的写入访问。

这反过来将结构/类转换为注释中概述的不可变类型。 这使得设计更加简洁。 我简单地重写了编译器抱怨的所有写入访问,以尊重不变的设计。 此后,结构和类很大程度上是可交换的,并且切换很容易。

唯一的麻烦是对结构的默认构造函数的调用,该类已不再存在于该类中。 但我不再需要它们,因为在课堂上,我可以简单地将这些情况设置为null


您可以对每个班级的非私人成员进行一次查找所有参考。 它会显示每个阅读和写给这些成员的信息。

链接地址: http://www.djcxy.com/p/79189.html

上一篇: Visual Studio: find all references of a specific type

下一篇: How does extern work in C#?