I'm trying to resolve CA2225, which WARNs on ContrainedValue<T>
below, with the following message: Provide a method named 'ToXXX' or 'FromXXX' as an alternate for operator 'ConstrainedValue<T>.implicit operator T(ConstrainedValue<T>)'.
I've also pasted PositiveInteger
to illustrate a use-case for ConstrainedValue<T>
. ConstrainedValue<T>
enables derivatives to simply specify the constraint being applied to a value type, in the constructor. It seems like a pretty clean way to code this up. Is there any way to resolve the CA2225 warning, given that I'm dealing with a generic type? How can I provide an alternate operator?
ToInt
, ToDouble
, etc. for all value types and have them throw if the from
is not of the same type? But I think it's a bad practice to have the ToXXX method throw?ConstrainedValue<T>
and PositiveInteger<T>
, a ConstrainedInteger
class. I could put ToInt()
in that class. But it seems wrong to create a layer simply to satisfy CA2225 and I don't think the warning would go away on ConstrainedValue<T>
and I would have to suppress that warning.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);
}
}
}
You can make the code analysis happy by actually doing what it says:
Insert this in ConstrainedValue<T>
and the warning will go away.
public T ToT()
{
return this.Value;
}
Personally, I'd rather suppress the message, you already provide a method to get the value even if the language does not provide casting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With