2016-04-25 36 views
6

Próbuję rozwiązać CA2225, który ostrzega o ContrainedValue<T> poniżej, z następującym komunikatem: Provide a method named 'ToXXX' or 'FromXXX' as an alternate for operator 'ConstrainedValue<T>.implicit operator T(ConstrainedValue<T>)'.Jak naprawić CA2225 (OperatorOverloadsHaveNamedAlternates) przy użyciu klasy rodzajowe

Ja również wklejony PositiveInteger do zilustrowania przypadków użycia dla ConstrainedValue<T>. ConstrainedValue<T> umożliwia instrumentom pochodnym proste określenie ograniczenia zastosowanego do typu wartości w konstruktorze. Wydaje się, że to całkiem czysty sposób, aby to zakodować. Czy istnieje sposób na rozwiązanie ostrzeżenia CA2225, biorąc pod uwagę, że mam do czynienia z typem generycznym? Jak mogę zapewnić alternatywnego operatora?

  • Być może zaimplementować ToInt, ToDouble, itd dla wszystkich typów wartości i je wyrzucić, jeśli from nie jest tego samego typu? Ale myślę, że niewłaściwą praktyką jest rzucanie metodą ToXXX?
  • Mogłem utworzyć warstwę pomiędzy klasami ConstrainedValue<T> i PositiveInteger<T>, ConstrainedInteger. W tej klasie mogę umieścić ToInt(). Ale wydaje się błędne stworzenie warstwy po prostu dla zaspokojenia CA2225 i nie sądzę, że ostrzeżenie zniknie na ConstrainedValue<T> i będę musiał wyłączyć to ostrzeżenie.

Kod:

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

Odpowiedz

3

Można dokonać analizy kodu szczęśliwy przez rzeczywiście robi to co mówi:

wstawić ten w ConstrainedValue<T> i ostrzeżenie odejdzie.

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

Osobiście wolałbym pominąć wiadomość, że już dostarczenie sposobu, aby uzyskać wartość, nawet jeśli język nie zapewnia odlew.

+0

Weird ... Tak naprawdę próbowałem to i ostrzeżenie pozostało, ale ponowne uruchomienie VS i rebuild naprawiono! W każdym razie myślę, że tłumienie ostrzeżenia jest z pewnością lepsze niż "ToT()", co może być mylące dla użytkownika końcowego. Dziękuję za odpowiedź! Pozostawi pytanie otwarte na inne pomysły. Chciałbym przedstawić czytelnych alternatywnych operatorów, takich jak ToInt, ToDouble itp., Ponieważ wydaje się, że jest to dobra praktyka, ale nie wiem, jaki jest najlepszy sposób na jej wdrożenie. Może to naprawdę nie ma znaczenia. – SFun28

+0

Przypuszczam, że mógłbym zaimplementować 'ToT()', utworzyć 'ConstrainedInteger', który wywodzi się z' ConstrainedValue' i zaimplementować 'ToInt', który po prostu wywołuje' ToT() ', a następnie wyprowadza' PositiveInteger' z 'ConstrainedInteger' – SFun28

+0

Właściwie , podejście odpowiadające nie działa w pełni. Generuje 'CA1000 - Nie deklaruj statycznych elementów na typach ogólnych '. LOL! – SFun28