泛型:传递int值而不是类型



这是我试图解决的问题。我需要向用户公开一组自定义类型。举几个例子:

var int2 = new FixedArray<int, VM2>(); // <=> ImmutableArray<int> / Length = 2
var double3 = new FixedArray<double, VM3>(); // <=> ImmutableArray<double> / Length = 3
var ushort6 = new FixedArray<ushort, VM6>(); // <=> ImmutableArray<ushort> / Length = 6
[...]

为了避免样板代码,我尝试对第二个参数使用泛型,结果是这样的:

sealed class FixedArray<T, VM> : IStructuralComparable where T : struct where VM : IVM, new()
{
public T[] array { get; init; }
public FixedArray()
{
VM vm = new VM(); // hopefully the compiler will do something smart
array = new T[vm.Value];
}
public int CompareTo(object? other, IComparer comparer) => ((IStructuralComparable)array).CompareTo(other, comparer);
}

:

interface IVM
{
int Value { get; }
}
sealed class VM2 : IVM
{
public VM2() { Value = 2; }
public int Value { get; }
}
sealed class VM3 : IVM
{
public VM3() { Value = 3; }
public int Value { get; }
}
sealed class VM6 : IVM
{
public VM6() { Value = 6; }
public int Value { get; }
}

在我的情况下,是否有其他技巧来传递整数(避免不同数组大小之间的高度冗余代码)?

更新:

VM可以是:

1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 8
  • 16
  • li> 1 - 2
  • 1 - 3
  • 1 - 8
  • 学会
  • 其它
  • 2-2n
  • 2 n
  • 3-3n
  • 3 n

在c#中没有真正的方法来做到这一点。泛型没有c++模板灵活。

如果有一些非常常用的数组长度,那么通常只是声明单独的类型。一个典型的例子是Vector2/3/4。这也使得添加只与特定长度相关的方法和属性变得更容易。

我并没有真正看到VM类型参数的优势。在我看来,省略它,直接输入

会更简单。
interface IFixedArray<T> where T : struct
{
T[] array {get;}
}
sealed class FixedArray2<T> : IFixedArray<T>
{
public T[] array {get;}
public FixedArray2() => array = new T[2];
}

您仍然需要为每个大小声明一个类,但是您去掉了一个泛型类型参数。可以将方法实现为扩展方法以避免重复,但如果需要实现某些接口,这可能不是另一种选择。如果是这种情况,一个公共基类可能是一个选择。

最新更新