只Array.ConvertAll()
處理一維數組。輸入應該是輸入類型的數組,併產生一個輸出類型的數組。該轉換器正在期待的東西,可以轉換object[,]
- >string[,]
。
多維數組沒有通用的轉換方法,你必須手工完成。你可以做這樣的事情:
public TOutput[,] ConvertAll<TInput, TOutput>(TInput[,] input, Func<TInput, TOutput> converter)
{
var length0 = input.GetLength(0);
var length1 = input.GetLength(1);
var result = new TOutput[length0, length1];
for (var i = 0; i < length0; ++i)
for (var j = 0; j < length1; ++j)
result[i, j] = converter(input[i, j]);
return result;
}
然後,你可以做到這一點做轉換:
var input = GetSelectedRange();
var converted = ConvertAll(input, x => x.ToString());
如果有可能的是,源陣列不爲0爲主,一些調整會需要做出處理改變的邊界。
public TOutput[,] ConvertAll<TInput, TOutput>(TInput[,] input, Func<TInput, TOutput> converter)
{
var lengths = new[] { input.GetLength(0), input.GetLength(1) };
var lowers = new[] { input.GetLowerBound(0), input.GetLowerBound(1) };
var uppers = new[] { input.GetUpperBound(0), input.GetUpperBound(1) };
var result = Array.CreateInstance(typeof(TOutput), lengths, lowers) as TOutput[,];
for (int i = lowers[0], il = uppers[0]; i <= il; ++i)
for (int j = lowers[1], jl = uppers[1]; j <= jl; ++j)
result[i, j] = converter(input[i, j]);
return result;
}
對於通用的轉換器,可以處理所有的陣列,這可以使用。
public Array ConvertAll<TInput, TOutput>(Array input, Func<TInput, TOutput> converter)
{
var rank = input.Rank;
var lengths = Enumerable.Range(0, rank).Select(i => input.GetLength(i)).ToArray();
var lowerBounds = Enumerable.Range(0, rank).Select(i => input.GetLowerBound(i)).ToArray();
var upperBounds = Enumerable.Range(0, rank).Select(i => input.GetUpperBound(i));
var output = Array.CreateInstance(typeof(TOutput), lengths, lowerBounds);
ConvertRank(input, converter, output, new int[0], lowerBounds.Zip(upperBounds, Tuple.Create).ToArray());
return output;
}
private void ConvertRank<TInput, TOutput>(Array input, Func<TInput, TOutput> converter, Array output, int[] indices, Tuple<int, int>[] bounds)
{
if (!bounds.Any())
{
var value = input.GetValue(indices);
var convertedValue = converter((TInput)value);
output.SetValue(convertedValue, indices);
}
else
{
var start = bounds[0].Item1;
var end = bounds[0].Item2;
var tail = bounds.Skip(1).ToArray();
for (var i = start; i <= end; i++)
ConvertRank(input, converter, output, indices.Concat(new[] { i }).ToArray(), tail);
}
}
您只需要將數組轉換回預期類型(因爲無法表示等級)。
object[,,] input = GetSome3dObjectArray();
var converted = ConvertAll(input, (object x) => x.ToString()) as string[,,];
如果你想要一些強大的打字,你可以爲你想要支持的類型創建適當的重載。
public TOutput[,] ConvertAll<TInput, TOutput>(TInput[,] input, Func<TInput, TOutput> converter) =>
ConvertAll((Array)input, converter) as TOutput[,];
public TOutput[,,] ConvertAll<TInput, TOutput>(TInput[,,] input, Func<TInput, TOutput> converter) =>
ConvertAll((Array)input, converter) as TOutput[,,];
@keyboardP但OP有'ToString' ... – Ian
Yep嘗試了複製方法,但因爲我的輸入包含字符串而出現錯誤。 –