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.
Cấu trúc 'có thể thay đổi' là một ý tưởng ** xấu **. – xanatos
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 –
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