Frage

OK, ich weiß, was Sie denken: "Warum eine Methode schreiben, von der Sie nicht möchten, dass die Leute verwenden?" Rechts?

Kurz gesagt, ich habe eine Klasse, die in XML serialisiert werden muss.Damit die XmlSerializer Um ihre Wirkung entfalten zu können, muss die Klasse einen standardmäßigen, leeren Konstruktor haben:

public class MyClass
{
  public MyClass()
  {
    // required for xml serialization
  }
}

Ich muss es also haben, aber ich möchte nicht, dass die Leute es haben verwenden es ist so Gibt es ein Attribut, mit dem die Methode als „NICHT VERWENDEN“ markiert werden kann?

Ich habe darüber nachgedacht, das zu verwenden Veraltet Attribut (da dies den Build stoppen kann), aber das scheint einfach irgendwie „falsch“ zu sein. Gibt es eine andere Möglichkeit, dies zu tun, oder muss ich weitermachen und in den sauren Apfel beißen?:) :)

Aktualisieren

OK, ich habe Keiths Antwort akzeptiert, da ich im Grunde meiner Meinung nach vollkommen zustimme.Aus diesem Grund habe ich die Frage überhaupt gestellt. Mir gefällt die Vorstellung nicht, das zu haben Veraltet Attribut.

Jedoch...

Dort Ist Immer noch ein Problem, während wir in Intellisense benachrichtigt werden. Idealerweise möchten wir den Build unterbrechen. Gibt es also eine Möglichkeit, dies zu tun?Vielleicht ein benutzerdefiniertes Attribut erstellen?

Es wurde eine gezieltere Frage erstellt Hier.

War es hilfreich?

Lösung

Wenn eine Klasse ist [Serialisable] (d. h.Es kann bei Bedarf an die entsprechende Stelle kopiert werden. Zur Deserialisierung wird der paramlose Konstruktor benötigt.

Ich vermute, dass Sie den Zugriff auf Ihren Code erzwingen möchten, um Standardwerte für Ihre Eigenschaften an einen parametrisierten Konstruktor zu übergeben.

Im Grunde sagen Sie, dass es für das in Ordnung ist XmlSerializer Sie möchten eine Kopie erstellen und dann Eigenschaften festlegen, aber Sie möchten nicht, dass Ihr eigener Code dies tut.

In gewisser Weise halte ich das für übertriebenes Design.

Fügen Sie einfach XML-Kommentare hinzu, die detailliert beschreiben, welche Eigenschaften initialisiert werden müssen (und was zu tun ist).

Nicht verwenden [Obsolete], weil es nicht so ist.Reservieren Sie dies für wirklich veraltete Methoden.

Andere Tipps

Sie können Folgendes verwenden:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]

sodass es nicht in Intellisence angezeigt wird.Wenn der Verbraucher es weiterhin verwenden möchte, kann er es zwar nutzen, es wird jedoch nicht so gut auffindbar sein.

Keiths Standpunkt zum Over-Engineering bleibt jedoch bestehen.

Ich las die Überschrift und dachte sofort „veraltetes Attribut“.Wie wäre es mit

    /// <summary>
    /// do not use
    /// </summary>
    /// <param name="item">don't pass it anything -- you shouldn't use it.</param>
    /// <returns>nothing - you shouldn't use it</returns>
    public bool Include(T item) { 
    ....

Eigentlich wäre ich geneigt, jedem zu widersprechen, der die Verwendung des befürwortet ObsoleteAttribute Wie die MSDN-Dokumentation besagt:

Durch das Markieren eines Elements als veraltet werden die Benutzer darüber informiert, dass das Element in zukünftigen Versionen des Produkts entfernt wird.

Da die generischen Konstruktoren für die XML-Serialisierung nicht aus der Anwendung entfernt werden sollten, würde ich sie nicht anwenden, nur für den Fall, dass ein späterer Wartungsentwickler nicht mit der Funktionsweise der XML-Serialisierung vertraut ist.

Ich habe tatsächlich verwendet Keiths Methode, bei der einfach vermerkt wird, dass der Konstruktor für die Serialisierung in der XML-Dokumentation verwendet wird, sodass er in Intellisense angezeigt wird.

Sie könnten Ihr eigenes bauen Attribute abgeleitete Klasse, sagen wir NonCallableAttribute um Methoden zu qualifizieren, und fügen Sie dann zu Ihrer Build-/CI-Code-Analyseaufgabe die Prüfung hinzu, um zu überwachen, ob Code diese Methoden verwendet.

Meiner Meinung nach kann man Entwickler wirklich nicht zwingen, die Methode nicht zu verwenden, aber man könnte so schnell wie möglich erkennen, wenn jemand gegen die Regel verstoßen hat, und das Problem beheben.

Wow, das Problem beschäftigt mich auch.

Sie benötigen auch Standardkonstruktoren für NHibernate, aber ich möchte die Leute zwingen, KEINE C# 3.0-Objektinitialisierer zu verwenden, damit Klassen den Konstruktorcode durchlaufen.

throw new ISaidDoNotUseException();

Trennen Sie Ihr serialisierbares Objekt von Ihrem Domänenobjekt.

Was Sie suchen, ist das ObsoleteAttribute Klasse:

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}

ObsoleteAttribute wird in Ihrer Situation wahrscheinlich funktionieren – Sie können sogar dazu führen, dass der Build kaputt geht, wenn diese Methode verwendet wird.

Da veraltete Warnungen zur Kompilierungszeit auftreten und die für die Serialisierung erforderliche Reflektion zur Laufzeit erfolgt, führt das Markieren dieser Methode als veraltet nicht zu einer Unterbrechung der Serialisierung, sondern zu einer Warnung der Entwickler, dass die Methode nicht zur Verwendung vorhanden ist.

Ich verwende das ObsoleteAttribute.

Aber Sie können natürlich auch einige Kommentare abgeben.

Und entfernen Sie es schließlich vollständig, wenn Sie können (Sie müssen nicht die Kompatibilität mit etwas Altem aufrechterhalten).Das ist der beste Weg.

Ja, das gibt es.

Ich habe diesen Blogbeitrag darüber geschrieben Zusammenarbeit mit dem Designer.

Und hier ist der Code:


public class MyClass
{
  [Obsolete("reason", true)]
  public MyClass()
  {
    // required for xml serialization
  }
}

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