2015-05-16 22 views
9

Tôi đã chuyển đổi cấu trúc (C#) thành lớp và cần phải sử dụng tất cả các loại sử dụng để đảm bảo rằng không có tác dụng không mong muốn nào của bản sao ẩn trước đây và hiện tại .Visual Studio: tìm tất cả các tham chiếu của một loại cụ thể

Có cách nào để tìm tất cả các tham chiếu, nơi mà loại cụ thể này được sử dụng/tham gia không?

Tôi đã thử Find all References trên loại và nhận tất cả các vị trí nơi tên loại được tuyên bố rõ ràng, đây là một khởi đầu tốt.

Tuy nhiên, tôi không nhận được các vị trí mà một thể hiện của loại này được trả về và sửa đổi. Cụ thể là các dòng mà tôi gán giá trị trả lại cho biến được nhập ngầm định bằng cách sử dụng var hoặc tất cả các bài tập cho các biến được xác định trước đó.

Có bất kỳ tính năng hoặc thủ thuật nào tôi có thể sử dụng không? Tôi đoán, trường hợp đặc biệt này của chuyển đổi cấu trúc thành lớp xảy ra khá thường xuyên. Có lẽ bạn có một số lời khuyên làm thế nào để tìm thấy tất cả các vấn đề có thể?

+2

Cấu trúc 'có thể thay đổi' là một ý tưởng ** xấu **. – xanatos

+1

Nếu bạn làm cho cấu trúc của bạn không thay đổi được, bạn không cần phải lo lắng về bất kỳ vấn đề nào trong số đó. Xem hướng dẫn thiết kế cấu trúc: https://msdn.microsoft.com/en-us/library/ms229031%28v=vs.110%29.aspx –

+0

Có, cấu trúc có thể thay đổi là xấu, nhưng thuận tiện. Nhưng bạn đúng. Bây giờ tôi phải đối mặt với hậu quả;) – azt

Trả lời

5

Bạn có thể đổi tên theo cách thủ công lớp ... mọi lỗi là một nơi mà nó được sử dụng. Nhưng tôi nghĩ rằng Visual Studio sẽ dừng lại sau một số lỗi nhất định.

Bạn có thể đánh dấu là [Obsolete] lớp học, tất cả các thuộc tính của nó, tất cả các phương pháp của nó. Sau đó, bạn sẽ có một cảnh báo mỗi khi bạn sử dụng chúng.

Lưu ý rằng [Obsolete] "lừa" có một số hạn chế:

[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 
} 

nên nó cũng giống như Find all References ...

Một giải pháp, dựa trên FxCop Phân tích/Mã của Visual Studio:

Đây là quy tắc tùy chỉnh, dựa trên hướng dẫn của http://blogs.msdn.com/b/codeanalysis/archive/2010/03/26/how-to-write-custom-static-code-analysis-rules-and-integrate-them-into-visual-studio-2010.aspx

Không gian tên mặc định của assem bly (bạn có thể đặt trong thuộc tính) phải là MyCustomFxCopRules. Nền tảng mục tiêu 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); 
} 

Các RuleMetadata.xml (nó phải là một Resource Embedded)

<?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> 

Dựa trên điều này, nó là sau đó dễ dàng để thêm các quy tắc khác đối với trường hợp góc khác mà tôi chắc chắn quên :-)

Tệp kiểm tra tôi đang sử dụng:

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) 
    { 

    } 
} 

Lưu ý rằng các quy tắc gỡ lỗi rất phức tạp ... Đó là khá dễ dàng để gỡ lỗi với FxCopCmd.exe, nhưng không thể (tôi nghĩ rằng, không chắc chắn) để gỡ lỗi khi được gọi trực tiếp bởi Visual Studio.

+0

Cả hai nhận xét của bạn là nhiều hơn hoặc ít hơn giống như tìm tất cả các tài liệu tham khảo. Sử dụng mẹo đổi tên trước khi VS giới thiệu tính năng này. Không biết thủ thuật '[Lỗi thời] '. Dù bằng cách nào, sẽ không trực tiếp giúp tôi ở đây. – azt

+0

@azt Từ quan điểm lý thuyết, có thể sửa đổi một máy phân tích IL để tìm tất cả các bài tập ... Cuối cùng bạn chỉ phải tìm tất cả 'stloc' cho kiểu của bạn, tất cả các cuộc gọi phương thức có tham số loại của bạn và như vậy ... – xanatos

+0

@azt nó có thể sử dụng Phân tích mã của Visual Studio ... Bạn phải viết một quy tắc tùy chỉnh ... nhưng nó là khá khó khăn để gỡ lỗi :-( – xanatos

1

Bạn có thể thực hiện Tìm tất cả các tham chiếu trên từng thành viên không phải là thành viên của từng nhóm, từng thành viên một. Nó sẽ hiển thị mọi đọc và viết cho những thành viên đó.

+0

Ông đã viết nó trong câu hỏi * Tôi đã thử ** Tìm tất cả Referenceson ** loại, và nhận được tất cả các địa điểm nơi tên loại được tuyên bố rõ ràng, đó là một khởi đầu tốt. * – xanatos

+1

Tìm tất cả các tài liệu tham khảo về loại là một điều. Tìm tất cả các tài liệu tham khảo trên, nói rằng, một tài sản lớp học, sẽ hiển thị mọi nơi mà tài sản đó được đọc hoặc viết, mà không giống như những gì OP mô tả ông đã làm –

+0

Bạn nói đúng, nó không nhất thiết phải là các bản sao ngầm tôi phải lo lắng, nhưng viết cho các thành viên công cộng. – azt

2

Câu trả lời và nhận xét đã đưa tôi đến một giải pháp thỏa đáng, có thể giúp người khác, vì vậy tôi nghĩ tôi sẽ đăng nó.

Câu hỏi không phải là quá nhiều để tìm tất cả các công dụng, nhưng chỉ có những câu hỏi "có vấn đề", cụ thể là viết quyền truy cập vào các thành viên công khai. Thay vì tìm tất cả các tham chiếu đến các thành viên, như được đề xuất trong this answer Tôi chỉ muốn tìm quyền truy cập ghi. Vì vậy, tôi đã sử dụng một chiến lược viết lại như được chỉ ra trong this answer và làm cho tất cả các thành viên chỉ viết, do đó trình biên dịch sẽ phàn nàn về quyền truy cập ghi nguy hiểm mà thôi.

Điều này lần lượt chuyển cấu trúc/lớp thành loại không thay đổi như được nêu trong các nhận xét. Điều này làm cho một thiết kế sạch hơn nhiều. Tôi chỉ đơn giản viết lại tất cả các truy cập viết nơi trình biên dịch phàn nàn, để tôn trọng thiết kế không thay đổi. Sau đó, cấu trúc và lớp học phần lớn có thể trao đổi và việc chuyển đổi dễ dàng.

Chỉ có sự cố là cuộc gọi đến các hàm tạo mặc định của cấu trúc, không còn tồn tại trong lớp nữa. Nhưng tôi không còn cần chúng nữa, vì với lớp tôi chỉ có thể đặt những trường hợp này thành null.

0

Nếu bạn đã cài đặt tiện ích Visual Studio Web Essentials thì rất dễ dàng. Kiểm tra ảnh chụp màn hình bên dưới. Khi nhấp vào liên kết được đánh dấu màu đỏ, bạn có thể xem tất cả tham chiếu của loại cụ thể. enter image description here

+0

Bạn có chắc chắn rằng không phải là một phần của studio hình ảnh cuối cùng? – JavierIEH

Các vấn đề liên quan