C# - 更改多维数组元素类型

时间:2018-02-28 17:15:25

标签: c# arrays multidimensional-array

我在编译时有一个未知维度的多维数组,但在运行时(当我收到这样的数组时),其维度被描述为int[] dimensionsdimensions的长度等于数组的等级,dimensions的每个元素都包含相关维度的长度。

我想要获得的是一个类似的Array,其元素映射到具有不同类型的新对象中。我认为LINQ可能有用所以我写了以下内容:

Array arr = ... //My multi-dimensional Array
var dimensions = ... //array describing the dimensions of arr. (NOT USED in the following but is an information i have)

var transformedArr = arr.Cast<StatusCode>().Select(val => JObject.FromObject(val)).ToArray();

虽然有效,但transformedArr现在只是一维数组,因此我失去了多维矩阵。 您是否有任何想法只能获得具有不同元素类型的相同数组?

请注意,我不知道数组的维度,仅在运行时。换句话说,我不能使用循环来索引多维数组。

任何想法都将受到赞赏:)

2 个答案:

答案 0 :(得分:1)

我认为以下功能应符合您的要求

public static void RecursiveCopy<TInput, TOutput>(
    Array source,
    Array destination,
    int[] dimensions,
    Func<TInput, TOutput> mutate,
    int[] indexPrefix = null)
{
    indexPrefix = indexPrefix ?? new int[0];
    if (dimensions.Length != 1)
    {
        for (var i = 0; i < dimensions[0]; i++)
        {
            var newDimensions = new int[dimensions.Length - 1];
            Array.Copy(dimensions, 1, newDimensions, 0, dimensions.Length - 1);

            var newIndexPrefix = new int[indexPrefix.Length + 1];
            Array.Copy(indexPrefix, 0, newIndexPrefix, 0, indexPrefix.Length);
            newIndexPrefix[indexPrefix.Length] = i;

            RecursiveCopy(source, destination, newDimensions, mutate, newIndexPrefix);
        }
    }
    else
    {
        var currentIndex = new int[indexPrefix.Length + 1];
        Array.Copy(indexPrefix, 0, currentIndex, 0, indexPrefix.Length);
        for (var i = 0; i < dimensions[0]; i++)
        {
            currentIndex[indexPrefix.Length] = i;
            var value = source.GetValue(currentIndex);
            if (value is TInput)
            {
                var mutated = mutate((TInput)value);
                destination.SetValue(mutated, currentIndex);
            }
            else
            {
                throw new ArgumentException("Different type. Expected " + nameof(TInput));
            }
        }
    }
}

用法

var transformedArr = Array.CreateInstance(typeof(StatusCode), dimensions);
RecursiveCopy<object, StatusCode>(arr, transformedArr, dimensions, i => i as StatusCode);

您可以输入真实类型而不是对象

答案 1 :(得分:0)

您可以使用CreateInstance创建输出数组(使用dimensions作为输入),然后使用GetValueSetValue转换您的值来实现此目的。< / p>