2016-04-25 5 views
6

Ich versuche CA2225, zu lösen, die unten auf ContrainedValue<T> warnt davor, mit der folgenden Meldung: Provide a method named 'ToXXX' or 'FromXXX' as an alternate for operator 'ConstrainedValue<T>.implicit operator T(ConstrainedValue<T>)'.Wie beheben CA2225 (OperatorOverloadsHaveNamedAlternates), wenn generische Klasse mit

ich auch PositiveInteger eingefügt haben einen Anwendungsfall zu veranschaulichen für ConstrainedValue<T>. ConstrainedValue<T> ermöglicht es, dass Derivate einfach die Constraint angeben, die auf einen Werttyp im Konstruktor angewendet werden. Es scheint eine ziemlich saubere Methode zu sein, dies zu kodieren. Gibt es eine Möglichkeit, die CA2225-Warnung zu lösen, da es sich um einen generischen Typ handelt? Wie kann ich einen alternativen Operator bereitstellen?

  • Vielleicht könnte ich implementieren ToInt, ToDouble usw. für alle Werttypen und haben sie werfen, wenn die from nicht vom gleichen Typ ist? Aber ich denke, es ist eine schlechte Übung, die ToXXX-Methode zu werfen?
  • Ich könnte eine Schicht zwischen ConstrainedValue<T> und PositiveInteger<T>, eine ConstrainedInteger Klasse erstellen. Ich könnte ToInt() in dieser Klasse setzen. Aber es scheint falsch, eine Schicht zu erstellen, nur um CA2225 zu erfüllen, und ich glaube nicht, dass die Warnung auf ConstrainedValue<T> weggehen würde, und ich würde diese Warnung unterdrücken müssen.

Code:

namespace OBeautifulCode.AutoFakeItEasy 
{ 
    using System.Diagnostics; 

    using Conditions; 

    /// <summary> 
    /// Represents a constrained value. 
    /// </summary> 
    /// <typeparam name="T">The type of the constrained value.</typeparam> 
    [DebuggerDisplay("{Value}")] 
    public abstract class ConstrainedValue<T> 
     where T : struct 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="ConstrainedValue{T}"/> class. 
     /// </summary> 
     /// <param name="value">The value of the <see cref="ConstrainedValue{T}"/> instance.</param> 
     protected ConstrainedValue(T value) 
     { 
      this.Value = value; 
     } 

     /// <summary> 
     /// Gets the underlying value of the instance. 
     /// </summary> 
     public T Value { get; } 

     /// <summary> 
     /// Performs an implicit conversion from <see cref="ConstrainedValue{T}"/> to the underlying value type. 
     /// </summary> 
     /// <param name="from">The <see cref="ConstrainedValue{T}"/> to convert from.</param> 
     /// <returns> 
     /// The result of the conversion. 
     /// </returns> 
     public static implicit operator T(ConstrainedValue<T> from) 
     { 
      return from.Value; 
     }    
    } 

    /// <summary> 
    /// Represents a positive integer. 
    /// </summary> 
    [DebuggerDisplay("{Value}")] 
    public sealed class PositiveInteger : ConstrainedValue<int> 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="PositiveInteger"/> class. 
     /// </summary> 
     /// <param name="value">The value held by the <see cref="PositiveInteger"/> instance.</param> 
     public PositiveInteger(int value) 
      : base(value) 
     { 
      Condition.Requires(value, nameof(value)).IsGreaterThan(0); 
     } 
    } 
} 

Antwort

3

können Sie die Code-Analyse glücklich machen, indem tatsächlich das tun, was er sagt:

Legen Sie diese in ConstrainedValue<T> und die Warnung wird weggehen.

public T ToT() 
{ 
    return this.Value; 
} 

Ich persönlich würde lieber die Meldung unterdrücken, haben Sie bereits ein Verfahren bereitstellen, um den Wert zu erhalten, auch wenn die Sprache nicht Gießen bietet.

+0

Seltsam ... Ich habe es tatsächlich versucht und die Warnung blieb, aber ein Neustart von VS und ein Wiederaufbau repariert es! Wie auch immer, ich denke, das Unterdrücken der Warnung ist sicherlich besser als 'ToT()', was für einen Endbenutzer wahrscheinlich verwirrend ist. Danke für die Antwort! Wird die Frage für andere Ideen offen halten. Ich möchte leserliche alternative Operatoren wie ToInt, ToDouble usw. anbieten, weil es eine gute Übung zu sein scheint, aber nicht sicher ist, was der beste Weg ist, das zu implementieren. Vielleicht ist es wirklich egal. – SFun28

+0

Ich könnte 'ToT()' implementieren, einen 'ConstrainedInteger' erzeugen, der von' ConstrainedValue' abgeleitet ist und ein 'ToInt' implementiert, das einfach' ToT() 'aufruft und dann' PositiveInteger' von 'ConstrainedInteger' abgeleitet wird. – SFun28

+0

Eigentlich , der beantwortete Ansatz funktioniert nicht vollständig. Es generiert 'CA1000 - Deklarieren Sie keine statischen Member für generische Typen'. LOL! – SFun28