这是我试图解决的问题。我需要向用户公开一组自定义类型。举几个例子:
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 4568
- 16
- li> 1 - 2 1 - 31 - 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];
}
您仍然需要为每个大小声明一个类,但是您去掉了一个泛型类型参数。可以将方法实现为扩展方法以避免重复,但如果需要实现某些接口,这可能不是另一种选择。如果是这种情况,一个公共基类可能是一个选择。