2015-02-24 12 views
5

Ich habe eine Klasse mit einem Member, die ich für Legacy-Code behalten muss, und ich muss es als veraltet markieren, damit neuer Code es nicht verwendet (ohne eine Warnung).Veraltetes Mitgliedsfeld mit Eigenschaft Accessor (Visual Studio Bug)

Sagen wir, die Klasse wie folgt aussieht:

class MyClass 
{ 
    [Obsolete] 
    private string _old = "..."; 

    [Obsolete] 
    public string Old 
    { 
     get { return _old; } 
    } 
} 

Ich erkläre, dass das Mitglied Feld _old veraltet ist, um sicherzustellen, dass neue Code innerhalb der Klasse nicht das Feld verwenden.

Ich erkläre auch, dass die Eigenschaft Old veraltet ist, um sicherzustellen, dass Code außerhalb der Klasse nicht die Eigenschaft verwenden.

Wenn ich dies kompiliere bekomme ich eine Warnung in der Eigenschaft Getter sagen, dass _old veraltet ist. Ich dachte, dass der Compiler dies ignorieren würde, da die Eigenschaft selbst veraltet ist.

Fehle ich etwas oder muss ich #pragma warning disable/restore für veraltete Mitgliedsfelder überall dort hinzufügen, wo sie verwendet werden (obwohl die Methode/Eigenschaft selbst als veraltet markiert ist)?


Der Grund, dass "Ich dachte, dass der Compiler diese leise ignorieren würde", weil es so für veraltete Klassen zu tun scheint:

[Obsolete] 
public class MyObsoleteClass 
{ 
    public string DoSomething() 
    { 
     // No warning here, since the class itself is obsolete 
     return new MyClass().Old; 
    } 
} 

Als @Heinzi beantwortet: diese scheint auf einen Fehler in Visual Studio zurückzuführen zu sein. Ich habe einen Bericht über connect eingereicht:

https://connect.microsoft.com/VisualStudio/feedback/details/1146809


Es stellt sich heraus, dass der Fehler in Visual Studio ist nicht nur beschränkt eine veraltete Feld von einer Eigenschaft zugreifen.

eine veraltete Eigenschaft von einer veralteten Methode Zugriff sollte keine Warnung ergeben:

public class Class2 
{ 
    [Obsolete] 
    public string Property { get; set; } 

    [Obsolete] 
    public void Method() 
    { 
     this.Property = "value"; // <-- Incorrect warning reported 
    } 
} 

Weder sollte so von einer anderen Klasse zu tun:

public class Class3 
{ 
    [Obsolete] 
    public string Property { get; set; } 
} 

public class Class4 
{ 
    [Obsolete] 
    public string Method() 
    { 
     return new Class3().Property; // <-- Incorrect warning reported 
    } 
} 

Interessanterweise funktioniert es in der folgenden Klasse und wenn Durch das Hinzufügen dieser Klasse werden die anderen Warnungen (von und Class2) auf magische Weise verschwinden.

public class Class5 
{ 
    [Obsolete] 
    public void Method() 
    { 
     // No warning reported here, which is good. 
     // This magically makes the other warnings disappear too! 
     new Class2().Method(); 
    } 
} 
+1

Warum den (internen) Code nicht umgestalten, um das richtige interne Feld zu verwenden? Dann haben Sie die Warnung nur einmal (für die Eigenschaft), für die das Obsolete-Attribut bestimmt ist - externe Verwendung. – HimBromBeere

+0

Ich muss das Feld behalten, wie es ist. Legacy-Code muss weiterhin verwendet werden. Dieser Code wird jedoch ebenfalls als veraltet markiert. Neuer Code soll die neuen Sachen benutzen, aber alter Code soll noch existieren und die alten Sachen benutzen können. –

+0

"* Ich dachte, dass der Compiler dies ignorieren würde, da die Eigenschaft selbst veraltet ist. *" Was hat Sie dazu gebracht? Gibt es etwas in der Dokumentation, das dies anzeigt? –

Antwort

2

Der Code ist in Ordnung, und Ihr Verständnis dafür, wie die Obsolete Attribut funktionieren sollte, ist richtig: Wenn Sie auf der Registerkarte „Output“ nach der Kompilierung betrachten, werden Sie feststellen, dass der Compiler nicht ausgibt eine Warnung für Ihren Fall (aber wird eine Warnung ausgeben, wenn Sie das Obsolete Attribut von Ihrer Eigenschaft entfernen, wie erwartet).

Sie haben jedoch Recht, dass Visual Studio manchmal eine Warnung anzeigt, nachdem der Code willkürlich geändert wurde. Dies scheint ein Fehler in Visual Studio zu sein.Wenn Sie es immer noch mit der aktuellsten Version reproduzieren können, würde ich vorschlagen, dass Sie einen Fehlerbericht unter http://connect.microsoft.com einreichen.

+0

Ich verwende Visual Studio 2013 mit Update 4. Nicht sicher, ob dies jedoch die aktuellste Version ist. –

+2

Ich habe mit dem Befehlszeilencompiler 'csc' überprüft. Keine Warnungen dort bekommen. Es scheint also ein Fehler in Visual Studio zu sein, wie du gesagt hast. –

0

Dies wäre eine clevere Funktion, aber ich sehe keine Hinweise in der Dokumentation, dass es sollte funktionieren auf diese Weise. Auf der anderen Seite würde ich das Attribut Obsolate nicht für ein privates Mitglied verwenden (wenn die Klasse nicht extrem groß ist), aber ich würde es stattdessen umgestalten. Ich Ihrem Fall würde ich schreiben:

class MyClass 
{ 
    [Obsolete] 
    public string Old 
    { 
     get; private set; 
    } 
} 

Und dann müssen Sie nur die Verwendungen von _old zu Old ändern, und das Problem ist gelöst.

+0

Ich muss das private Mitglied behalten. Sowohl für den Legacy-Code innerhalb der Klasse als auch für den Serialisierungsvertrag. –

+0

Gut für den alten Code wäre das keine allzu gefährliche Veränderung. (Wenn es Ihnen nicht explizit untersagt ist, Änderungen daran vorzunehmen.) Ich kenne den Serialisierungsvertrag nicht, daher kann ich leider nichts dazu sagen ... –