c# - 如何创建未知多维参数?
问题描述
我想知道是否可以创建一个通用的多维参数。我正在制作一个通用列表/数组洗牌类,它有一个静态方法,它获取一个 IEnumerable 参数并返回相同但已经洗牌。问题是我不知道如何使参数如此通用以至于它可以获得任意数量的维度数组/列表。
先感谢您。
这是我现在写的代码:
public static IEnumerable<T> OneDimensionalShuffle<T>(IEnumerable<T> array)
{
var originalList = array.ToList();
var shuffledList = new List<T>();
var rand = new Random();
for (var i = originalList.Count - 1; i >= 0; i--)
{
var randomArrayPosition = rand.Next(i + 1); //i+1 because maxValue is exclusive
shuffledList.Add(originalList[randomArrayPosition]); //Add random point to the shuffledList
originalList.RemoveAt(randomArrayPosition); //Remove element which was already added to shuffledList
}
array = shuffledList;
return array;
}
解决方案
据我所知,没有办法访问任意等级的通用类型多维数组。
备选方案 1:使用无类型数组
Array arr = new int[1,1];
var rank = arr.Rank;
var value = arr.GetValue(0,0);
这样做的缺点是它相当慢,并且会导致一堆拳击。
备选方案 2:使用自定义多维类型
public class MyMultiDimensionalArray<T>{
public T[] backingDataStorage {get;}
public int Rank {get;}
public int[] Length {get;}
public T GetValue(params int[] indices){
// Math to convert the indices to a one dimensional value
}
}
这样做的一个优点是您可以使用泛型类型,并允许直接访问底层数组。缺点是您需要编写一堆数学来将任意等级的索引转换为一维索引。这种情况的一个变体是具有不同的类型,My2DArray、My3DArray 等,以及一个通用接口。
备选方案 3:根据需要定义尽可能多的方法
public static void MyMethod<T>(T[]) { /*...*/}
public static void MyMethod<T>(T[,]) { /*...*/}
public static void MyMethod<T>(T[,,]) { /*...*/}
public static void MyMethod<T>(T[,,,]) { /*...*/}
这很容易做到并允许通用类型,但需要大量重复代码。
根据我的经验,1d、2d 和 3d 数组是最常见的。我从未见过在野外使用的 4d 数组。甚至 3d 数组也经常变得如此之大,以致于将一维存储为锯齿状数组(即 int[][,])会更好,因为它避免了需要巨大的连续内存块,允许锁定单个切片等。更喜欢使用自定义多维数组类型,因为我发现想要对数据进行线性访问是很常见的,比如序列化或洗牌。
推荐阅读
- django - Django:从管理员的静态文件夹中渲染图像
- batch-file - 使用 sed 和 bc 在文本文件中计算
- python - 如何对不同的迭代值求和?
- swift - RealmSwift:如何将多个对象添加到多对一关系?
- python - SoupStrainer 根本不提高速度
- c++ - 我的 IF 语句中的问题,Else 无法正常工作
- html-lists - QTextBrowser 显示带有多余空格的嵌套 HTML 列表
- java - 如何修复“volte_imsvt1 无法连接”错误
- python - 张量操作python中的内存和时间
- c# - 在 UWP 应用程序中检测睡眠事件或唤醒事件