Frage

Wenn die ObsoleteAtribute in .NET es Ihnen Warnungen Compiler sagen Sie gibt, dass die Objekt / Methode / Eigenschaft ist veraltet und somthing anderes verwendet werden soll. Ich arbeite derzeit an einem Projekt, das viel Refactoring einen Ex-Mitarbeiter Code erfordert. Ich möchte ein benutzerdefiniertes Attribut schreiben, die ich verwenden können, Methoden oder Eigenschaften zu markieren, die Compiler-Warnungen generiert, die Nachrichten geben, die ich schreibe. So etwas wie diese

[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

Das möchte ich eine Compiler-Warnung zu erzeugen, die sagt: „Dieser Code sux und sollte betrachtet werden“. Ich weiß, wie ein benutzerdefiniertes Attribut erstellen, die Frage ist, wie ich es verursache Compiler-Warnungen in Visual Studio zu erzeugen.

War es hilfreich?

Lösung

Update

Dies ist nun möglich, mit Roslyn (Visual Studio 2015). Sie können bauen = "https: // github.com/dotnet/roslyn/wiki/How-To-Write-aC%23-Analyzer-and-Code-Fix“rel = "nofollow noreferrer"> Code Analyzer für ein benutzerdefiniertes Attribut überprüfen


Ich glaube nicht, es ist möglich. ObsoleteAttribute wird speziell vom Compiler behandelt und wird in dem C # Standard definiert. Warum auf der Erde ist ObsoleteAttribute nicht akzeptabel? Es scheint mir, wie das ist genau die Situation es, entworfen wurde und erreicht genau das, was Sie benötigen!

Beachten Sie, dass Visual Studio nach oben nimmt die von ObsoleteAttribute on the fly generiert Warnungen zu, was sehr nützlich ist.

Bedeuten nicht, nicht hilfreich sein, nur fragen, warum Sie sich mit nicht scharf sind ...

Leider ObsoleteAttribute abgedichtet ist (wahrscheinlich zum Teil durch die spezielle Behandlung) daher können Sie nicht Ihr eigenes Attribut es eine Unterklasse.

Von dem C # Standard: -

  

Das Attribut Obsolete wird verwendet, um zu markieren   Typen und Mitglieder von Typen, die sollten   nicht mehr verwendet werden.

     

Wenn ein Programm verwendet einen Typ oder Member   dass mit dem veralteten dekoriert   Attribut, gibt der Compiler eine   Warnung oder ein Fehler. Genauer gesagt, die   Compiler gibt eine Warnung aus, wenn kein Fehler   Parameter vorgesehen ist, oder wenn der Fehler   Parameter ist vorgesehen und hat die   Wert false. Der Compiler gibt eine   Fehler, wenn die Fehlerparameter ist   angegeben und hat den Wert true.

Ist nicht diese Summe auf Ihre Bedürfnisse? ... Sie gehen zu tun besser nicht als das glaube ich nicht.

Andere Tipps

Sie wissen nicht, ob dies funktionieren wird, aber es ist ein Versuch wert.

Sie können nicht abgekündigt verlängern, weil seine endgültige, aber vielleicht können Sie Ihr eigenes Attribut erstellen, und diese Klasse als veraltet wie folgt markieren:

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

Dann, wenn Sie Ihre Methoden mit dem „MustRefactor“ Attribute markieren, könnten die kompilieren Warnungen zeigen.

Ich sagte, „vielleicht“ und „könnte“, weil ich habe nicht versucht. Bitte sagen Sie mir, wenn es nicht so funktioniert ich die Antwort entfernen würde.

Viele Grüße!

UPDATE: Getestet es. Es erzeugt eine Kompilierung Warnung, aber die Fehlermeldung sieht komisch aus, können Sie es selbst sehen sollte und wählen. Das ist ganz in der Nähe, was Sie erreichen wollten.

UPDATE2: Mit dieser Code Es erzeugt Diese Warnungen (nicht sehr schön, aber ich glaube nicht, dass es etwas besser).

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
{

}

In einigen Compiler können Sie #WARNING verwenden, um eine Warnung zu erteilen:

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

In Microsoft-Compiler, können Sie in der Regel die Nachricht Pragma verwenden:

#pragma message ( "text" )

Sie haben erwähnt, .Net, aber nicht angeben, ob Sie mit C / C ++ oder C # programmiert wurden. Wenn Sie in c # programmieren, als Sie sollten wissen, dass C # unterstützt die #WARNING Format .

Wir sind momentan in der Mitte viel Refactoring, wo wir nicht alles sofort beheben konnte. Wir verwenden nur die #WARNING preproc Befehl, wohin wir gehen müssen zurück und Code zu suchen. Es zeigt sich in der Compilerausgabe auf. Ich glaube nicht, dass Sie es auf einer Methode setzen können, aber man konnte es ausdrückte nur innerhalb der Methode, und es ist immer noch leicht zu finden.

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

In VS 2008 (+ sp1) #warnings zeigt nicht richtig in Fehlerliste nach dem Reinigen & Soultion Mappe neu erstellen, nicht alle von ihnen. Einige Warnungen werden in der Fehlerliste zeigt erst, nachdem ich bestimmte Klasse-Datei öffnen. So war ich gezwungen, benutzerdefinierte Attribute zu verwenden:

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

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

    public MappingToDo()
    {}
}

Wenn ich also markieren einen Code mit ihm

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

Es produziert Warnungen wie folgt aus:

  

Namespace.MappingToDo ist veraltet:   'Mapping ToDo'.

Ich kann nicht den Text der Warnung ändern, ‚Einiger Kommentar‘ wird gezeigt, nicht Liste Fehler. Aber es wird auf die richtige Stelle in der Datei springen. Wenn Sie also solche Warnmeldungen zu ändern, erstellen Sie verschiedene Attribute.

Was Sie versuchen zu tun, ist ein Missbrauch von Attributen. Verwenden Sie stattdessen das Visual Studio Task-Liste. Sie können einen Kommentar in dem Code wie folgt eingeben:

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

Dann öffnet Ansicht / Aufgabenliste aus dem Menü. Die Aufgabenliste hat zwei Kategorien, Benutzeraufgaben und Kommentare. Wechseln Sie Kommentare, und Sie werden alle Ihre // Todo sehen: 's gibt. Ein Doppelklick auf einen TODO wird in Ihrem Code auf den Kommentar springen.

Al

Ich glaube nicht, Sie können. Soweit ich für ObsoleteAttribute unterstützen wissen, im Wesentlichen in den C # -Compiler fest einprogrammiert ist; Sie können nichts tun, ähnlich direkt.

Was Sie könnten in der Lage sein zu tun ist, verwenden Sie eine MSBuild-Aufgabe (oder ein Post-Build-Ereignis), die ein benutzerdefiniertes Werkzeug gegen die soeben kompilierte Assembly ausführt. Das Anpassungs-Tool würde alle Arten / Methoden in der Montage reflektiert über und Ihr benutzerdefiniertes Attribut verbrauchen, an welcher Stelle es zu System.Console der Ausfall- oder Fehlern TextWriters drucken kann.

an der Quelle der Suche nach ObsoleteAttribute , es doesn ‚t aussehen, wie es etwas zu tun, ist etwas besonderes eine Compiler-Warnung zu erzeugen, also würde ich mit @ gehen neigen technophile und sagen, dass es hart codiert in den Compiler ist. Gibt es einen Grund, warum Sie nicht wollen, verwenden nur ObsoleteAttribute Ihre Warnmeldungen generieren?

Es gibt mehrere Kommentare, die zum Einfügen von Warnungen oder Pragma vorschlagen. Veraltete Werke auf eine ganz andere Art und Weise! Kennzeichnung obsolet eine Funktion einer Bibliothek L, die veraltete Nachricht erhöht, wenn ein Programm die Funktion aufruft, auch wenn das Anrufer-Programm ist nicht in der Bibliothek L. Warnung die Meldung wirft nur, wenn L kompiliert wird.

Hier ist die Roslyn Implementierung, so dass Sie Ihre eigenen Attribute erstellen können, die Warnungen oder Fehler im laufenden Betrieb geben.

Ich habe ein Attribut Typen erstellen IdeMessage aufgerufen, die das Attribut wird die Warnungen generiert:

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

    public IDEMessageAttribute(string message);
}

Um dies Sie tun müssen, die Roslyn SDK ersten und starten Sie ein neues Projekt mit VSIX Analysator installieren. Ich habe einige der weniger relevanten Stück wie die Nachrichten weggelassen, können Sie herausfinden, wie das zu tun. In Ihrem Analysator tun Sie dies

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);
}

Es gibt keine CodeFixProvider für diese Sie es aus der Lösung entfernt werden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top