我正在尝试将object[,]
数组(例如其中的一些整数)转换为string[,]
数组。我写了这段代码,但Visual Studio给了我一个错误说:
无法将
String[]
隐式转换为String[,]
。
我应该对Array.ConvertAll
函数给出什么论点?非常感谢。
object[,] input = GetSelectedRange();
string[,] dst = Array.ConvertAll<object[,], string[,]>(
input,
x => x.ToString()
);
答案 0 :(得分:4)
如果您的商品是object[][]
而不是object[,]
,那将会容易得多。但是对于object[,]
,为什么不使用传统方法?
object[,] input = GetSelectedRange();
string[,] output = new string[input.GetLength(0), input.GetLength(1)];
for (int i = 0; i < input.GetLength(0); ++i)
for (int j = 0; j < input.GetLength(1); ++j)
output[i, j] = input[i, j]?.ToString(); //give additional ?. to check if your input is null
Olivier的建议:使用C#6语法检查输入是否为空?.
或者,如果您使用较低版本,请使用三元运算符:
object[,] input = GetSelectedRange();
string[,] output = new string[input.GetLength(0), input.GetLength(1)];
for (int i = 0; i < input.GetLength(0); ++i)
for (int j = 0; j < input.GetLength(1); ++j)
output[i, j] = input[i, j] == null ? null input[i, j].ToString();
答案 1 :(得分:3)
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[,,];
答案 2 :(得分:0)
来自:https://stackoverflow.com/a/5083690/380384
object[,] src = new object[2, 3];
// Initialize src with test strings.
src[0, 0] = "aa";
src[0, 1] = "ab";
src[0, 2] = "ac";
src[1, 0] = "ba";
src[1, 1] = "bb";
src[1, 2] = "bc";
string[,] dst = new string[src.GetLength(0), src.GetLength(1)];
Array.Copy(src, dst, src.Length);
请注意,这不是转换而是重新转换。如果object
元素实际上是string
元素(例如来自Excel
工作表的元素),则它可以正常工作。