문제

.Net에서 ObsoleteAtribute를 사용하면 개체/메서드/속성이 더 이상 사용되지 않으며 다른 것을 사용해야 한다는 컴파일러 경고가 표시됩니다.저는 현재 전 직원 코드를 많이 리팩토링해야 하는 프로젝트를 진행하고 있습니다.내가 작성한 메시지를 제공하는 컴파일러 경고를 생성하는 메서드나 속성을 표시하는 데 사용할 수 있는 사용자 지정 특성을 작성하고 싶습니다.이 같은

[MyAttribute("This code sux and should be looked at")]
public void DoEverything()
{
}
<MyAttribute("This code sux and should be looked at")>
Public Sub DoEverything()
End Sub

"이 코드는 sux이며 살펴봐야 합니다"라는 컴파일러 경고를 생성하고 싶습니다.사용자 지정 특성을 만드는 방법을 알고 있습니다. 문제는 Visual Studio에서 컴파일러 경고를 생성하는 방법입니다.

도움이 되었습니까?

해결책

업데이트

이것은 이제 Roslyn (Visual Studio 2015)에서 가능합니다. 당신은 할 수 있습니다 짓다코드 분석기 사용자 정의 속성을 확인합니다


나는 그것이 가능하다고 믿지 않는다. ObsoleTeatTribute는 컴파일러에 의해 특별히 처리되며 C# 표준에 정의되어 있습니다. 왜 지구상에서 쓸모 없는지 공물이 허용되지 않습니까? 이것이 바로 이것이 그것이 설계된 상황 인 것처럼 보이며, 당신이 필요로하는 것을 정확하게 달성합니다!

또한 Visual Studio는 ObsoleTeatTribute에서 생성 된 경고를 즉시 선택하여 매우 유용합니다.

도움이되지 않는다는 의미는 아니며 왜 당신이 그것을 사용하는 데 관심이 없는지 궁금합니다 ...

불행히도 불명예가 발생하여 (특별한 치료로 인해 부분적으로) 밀봉되어 있으므로 자신의 속성을 하위 클래식 할 수 없습니다.

C# 표준에서 :-

쓸모없는 속성은 더 이상 사용해서는 안되는 유형의 유형 및 구성원을 표시하는 데 사용됩니다.

프로그램이 쓸모없는 속성으로 장식 된 유형 또는 멤버를 사용하는 경우 컴파일러는 경고 또는 오류를 발행합니다. 구체적으로, 컴파일러는 오류 매개 변수가 제공되지 않거나 오류 매개 변수가 제공되고 값이 false 인 경우 경고를 발행합니다. 오류 매개 변수가 지정되고 값이 true가 있으면 컴파일러가 오류를 발행합니다.

그것이 당신의 요구를 요약하지 않습니까? ... 당신은 내가 생각하지 않는 것보다 더 잘하지 않을 것입니다.

다른 팁

이것이 효과가 있는지 모르지만 시도해 볼 가치가 있습니다.

최종적이기 때문에 쓸모없는 확장을 확장 할 수는 없지만 자신만의 속성을 만들고 해당 클래스를 다음과 같이 쓸모없는 것으로 표시 할 수 있습니다.

[Obsolete("Should be refactored")]
public class MustRefactor: System.Attribute{}

그런 다음 "MustRefactor"속성으로 메소드를 표시하면 컴파일 경고가 표시 될 수 있습니다.

나는 이것을 시도하지 않았기 때문에 "아마도"와 "할 수있다"고 말했다. 작동하지 않으면 답을 제거하겠습니다.

문안 인사!

업데이트 : 테스트했습니다. 컴파일 타임 경고를 생성하지만 오류 메시지는 재미있어 보이며 직접보고 선택해야합니다. 이것은 당신이 달성하고자하는 것에 매우 가깝습니다.

업데이트 2 : 이 코드 그것은 생성됩니다 이 경고 (그다지 좋지는 않지만 더 나은 것이 있다고 생각하지 않습니다).

public class User
{
    private String userName;

    [TooManyArgs] // Will show warning: Try removing some arguments
    public User(String userName)
    {
        this.userName = userName;   
    }

    public String UserName
    {
        get { return userName; }
    }
    [MustRefactor] // will show warning: Refactor is needed Here
    public override string ToString()
    {
        return "User: " + userName;
    }
}
[Obsolete("Refactor is needed Here")]
public class MustRefactor : System.Attribute
{

}
[Obsolete("Try removing some arguments")]
public class TooManyArgs : System.Attribute
{

}

일부 컴파일러에서는 #Warning을 사용하여 경고를 발행 할 수 있습니다.

#warning "Do not use ABC, which is deprecated. Use XYZ instead."

Microsoft 컴파일러에서 일반적으로 메시지 Pragma를 사용할 수 있습니다.

#pragma message ( "text" )

.NET을 언급했지만 C/C ++ 또는 C#으로 프로그래밍 중인지 여부를 지정하지 않았습니다. C#로 프로그래밍하는 경우 알아야합니다. C #은 #Warning 형식을 지원합니다.

우리는 현재 모든 것을 바로 수정할 수없는 많은 리팩토링의 중간에 있습니다. 우리는 단지 #Warning PREPROC 명령을 사용하여 돌아가서 코드를보아야합니다. 컴파일러 출력에 나타납니다. 나는 당신이 그것을 방법에 넣을 수 있다고 생각하지 않지만, 당신은 그것을 메소드 안에 넣을 수 있지만 여전히 찾기가 쉽습니다.

public void DoEverything() {
   #warning "This code sucks"
}

VS 2008(+sp1)에서는 Clean Soultion 및 Rebuild Solution 후 #warnings가 오류 목록에 제대로 표시되지 않습니다. 전부 표시되지는 않습니다.일부 경고는 특정 클래스 파일을 연 후에만 오류 목록에 표시됩니다.그래서 강제로 맞춤 속성을 사용해야 했습니다.

[Obsolete("Mapping ToDo")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
public class MappingToDo : System.Attribute
{
    public string Comment = "";

    public MappingToDo(string comment)
    {
        Comment = comment;
    }

    public MappingToDo()
    {}
}

그래서 일부 코드에 플래그를 지정하면

[MappingToDo("Some comment")]
public class MembershipHour : Entity
{
    // .....
}

다음과 같은 경고가 생성됩니다.

Namespace.MappingToDo는 더 이상 사용되지 않습니다.'할일 매핑'.

경고 텍스트를 변경할 수 없습니다. '일부 댓글'에 오류 목록이 표시되지 않습니다.그러나 파일의 적절한 위치로 이동합니다.따라서 이러한 경고 메시지를 변경해야 하는 경우 다양한 속성을 생성하세요.

당신이하려는 것은 속성의 오용입니다. 대신 Visual Studio 작업 목록을 사용하십시오. 다음과 같은 코드에 주석을 입력 할 수 있습니다.

//TODO:  This code sux and should be looked at
public class SuckyClass(){
  //TODO:  Do something really sucky here!
}

그런 다음 메뉴에서보기 / 작업 목록을 엽니 다. 작업 목록에는 두 가지 범주, 사용자 작업 및 댓글이 있습니다. 주석으로 전환하면 모든 // todo : 's가 있습니다. TODO를 두 번 클릭하면 코드의 주석으로 이동합니다.

나는 당신이 할 수 없다고 생각합니다. 내가 아는 한, ObsoleTeatTribute에 대한 지원은 본질적으로 C# 컴파일러로 하드 코딩됩니다. 당신은 비슷한 일을 직접 할 수 없습니다.

당신이 할 수있는 것은 방금 컴파일 된 어셈블리에 대해 사용자 정의 도구를 실행하는 MSBuild 작업 (또는 건축 후 이벤트)을 사용하는 것입니다. 사용자 정의 도구는 어셈블리의 모든 유형/메소드에 대해 반영되고 사용자 정의 속성을 소비하며,이 시점에서 시스템에 인쇄 할 수 있습니다.

소스를보고 있습니다 쓸모없는 목적, 컴파일러 경고를 생성하기 위해 특별한 일을하는 것처럼 보이지 않으므로 @와 함께 이동하는 경향이 있습니다.Technophile 컴파일러에 하드 코딩된다고 말합니다. 만 사용하고 싶지 않은 이유가 있습니까? 쓸모없는 목적 경고 메시지를 생성하려면?

경고 나 프라그마를 삽입 할 것을 제안하는 몇 가지 의견이 있습니다. 쓸모없는 것은 매우 다른 방식으로 작동합니다! 쓸모없는 마킹 라이브러리 L의 함수 L, LIBRATER L의 함수는 발신자 프로그램이 라이브러리 L에 있지 않더라도 프로그램이 기능을 호출 할 때 발생합니다. 경고는 L을 컴파일 할 때만 메시지를 제기합니다.

Roslyn 구현은 다음과 같습니다. 따라서 즉시 경고 나 오류를 제공하는 고유 한 속성을 만들 수 있습니다.

호출 된 속성 유형을 만듭니다 IdeMessage 경고를 생성하는 속성이 될 것입니다.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class IDEMessageAttribute : Attribute
{
    public string Message;

    public IDEMessageAttribute(string message);
}

이를 위해서는 먼저 Roslyn SDK를 설치하고 분석기를 사용하여 새로운 VSIX 프로젝트를 시작해야합니다. 나는 메시지와 같은 덜 관련성있는 부분을 생략했는데, 당신은 그것을하는 방법을 알아낼 수 있습니다. 분석기에서는이 작업을 수행합니다

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzerInvocation, SyntaxKind.InvocationExpression);
}

private static void AnalyzerInvocation(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;

    var methodDeclaration = (context.SemanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol as IMethodSymbol);

    //There are several reason why this may be null e.g invoking a delegate
    if (null == methodDeclaration)
    {
        return;
    }

    var methodAttributes = methodDeclaration.GetAttributes();
    var attributeData = methodAttributes.FirstOrDefault(attr => IsIDEMessageAttribute(context.SemanticModel, attr, typeof(IDEMessageAttribute)));
    if(null == attributeData)
    {
        return;
    }

    var message = GetMessage(attributeData); 
    var diagnostic = Diagnostic.Create(Rule, invocation.GetLocation(), methodDeclaration.Name, message);
    context.ReportDiagnostic(diagnostic);
}

static bool IsIDEMessageAttribute(SemanticModel semanticModel, AttributeData attribute, Type desiredAttributeType)
{
    var desiredTypeNamedSymbol = semanticModel.Compilation.GetTypeByMetadataName(desiredAttributeType.FullName);

    var result = attribute.AttributeClass.Equals(desiredTypeNamedSymbol);
    return result;
}

static string GetMessage(AttributeData attribute)
{
    if (attribute.ConstructorArguments.Length < 1)
    {
        return "This method is obsolete";
    }

    return (attribute.ConstructorArguments[0].Value as string);
}

솔루션에서 제거 할 수있는 CodeFixProvider는 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top