【发布时间】:2021-07-15 18:52:09
【问题描述】:
我目前有一个泛型接口和一个泛型类型,分别是ISignal<T> 和SignalValue<T>。但是,我对 SignalValue 的 <T> 有一个限制,要求 T 具有可比性。
每个的简化版本如下:
public interface ISignal<T> where T : IComparable
{
string FullName { get; }
public void SetValue(SignalValue<T> value, bool withLog = true);
public SignalValue<T> GetValue(int readDelayMs = 500);
}
public class SignalValue<T> : IEquatable<T>, IComparable<T>, IComparable, ISignalValue where T : IComparable
{
public readonly T Value;
public SignalValue(T value)
{
Value = value;
}
public virtual int CompareTo(T other)
{
return Value.CompareTo(other);
}
}
SignalValue<T> 主要用作 T 是 bool 或 double 的值的包装器,并带有一些附加的属性。然而,一旦我有了这个约束,我发现由于装箱约束正在到处传播。例如,我有以下静态方法,它显然也需要约束,即使它对任何与比较相关的内容没有真正的依赖关系:
public static void DoSequence<T>(ISignal<T> signal, List<SequencePair<T>> pair) where T : IComparable
{
if (signal == null) throw new ArgumentNullException(nameof(signal));
if (pair == null) throw new ArgumentNullException(nameof(pair));
if (pair.Count <= 0) return;
List<SequencePair<T>> orderedList = pair.OrderBy(p => p.Seconds).ToList();
//... more stuff but no comparison at all
}
我理解为什么需要这个约束,但这也让我想知道在我的类中使用对泛型类型的约束来设置它是否是代码异味。有没有什么方法可以让我的类在使用 SignalValue<T> 的地方仍然需要一个可比较的类型,而不需要在整个代码中进行约束?
【问题讨论】:
-
“我明白为什么需要这个约束” -- 那么你也明白为什么你需要在任何你使用
SignalValue<T>的地方提供这个约束。如果您不提供约束,编译器应该如何验证您的类型参数与SignalValue<T>一起使用是否合法。是什么让你认为你应该能够摆脱它? -
我不认为我应该能够逃脱它 - 这就是为什么句子的第二部分说“......想知道是否通过对泛型类型的约束来设置它在我的班级里有一种代码味道”,这意味着我想知道是否有更好的方法。也许我应该更笼统,只是问“有没有更好的方法”。我在最后一句中这样做了,但我想我在询问该类是否需要该类型时过于具体。无论如何,@JonasH 在下面回答这个问题。
-
如果
DoSequence是SignalValue<T>内部的静态方法,那么您不需要重新声明T
标签: c# generics constraints