如何为T[], T[][]编写重载的泛型扩展方法而不产生歧义
本文关键字:方法 扩展 歧义 泛型 重载 | 更新日期: 2023-09-27 18:16:13
我想写一个扩展方法转换向量和矩阵到字符串。我是这样做的。
为向量public static string GetString<T>(this T[] SourceMatrix, string ColumnDelimiter = " ")
{
try
{
string result = "";
for (int i = 0; i < SourceMatrix.GetLength(0); i++)
result += SourceMatrix[i] + ColumnDelimiter;
return result;
}
catch (Exception ee) { return null; }
}
矩阵的public static string GetString<T>(this T[][] SourceMatrix, string ColumnDelimiter = " ", string RowDelimiter = "'n")
{
try
{
string result = "";
for (int i = 0; i < SourceMatrix.GetLength(0); i++)
{
for (int j = 0; j < SourceMatrix[i].GetLength(0); j++)
result += SourceMatrix[i][j] + "" + ColumnDelimiter;
result += "" + RowDelimiter;
}
return result;
}
catch (Exception ee) { return null; }
}
现在我正在使用下面的代码,这会导致歧义。
List<double[]> Patterns= GetPatterns();
Patterns.ToArray().GetString();
误差Error 5 The call is ambiguous between the following methods or properties:
'MatrixMathLib.MatrixMath.GetString<double[]>(double[][], string)' and
'MatrixMathLib.MatrixMath.GetString<double>(double[][], string, string)'
谁能建议我正确地编写这些扩展方法?
你的方法没有问题。是编译器无法在它们之间做出选择。
在错误消息中可以看到,编译器可以假设T
是double[]
并匹配第一个方法,或者double
并匹配第二个方法。这个问题可以通过显式地指明要使用的方法来解决:
Patterns.ToArray().GetString<double>();
可以省略默认值,也可以在函数调用中声明T的类型
编译器无法判断您是要调用GetString<double[]>
还是GetString<double>
,因为这两个方法都适合调用。
解决这个问题的最简单方法是简单地更改其中一个名称(即GetArrayString<T>
)。在我看来,一个更好的解决方案是只有一种方法可以同时解决这两种情况:
public static string Join<T>(this T[] sourceMatrix, string columnDelimiter = " ", string rowDelimiter = "'n")
{
if (sourceMatrix.Length == 0)
{
return string.Empty;
}
if (sourceMatrix[0] as Array == null)
{
return string.Join(columnDelimiter, sourceMatrix);
}
var rows = new List<string>();
foreach (T item in sourceMatrix)
{
var array = item as Array;
var row = "";
for (int j = 0; j < array.GetLength(0); j++)
row += array.GetValue(j) + columnDelimiter;
rows.Add(row);
}
return string.Join(rowDelimiter, rows);
}
用法:
int[] a = {1, 2, 3};
int[] b = { 1, 2, 4 };
int[][] c = {a, b};
Console.WriteLine(a.Join());
Console.WriteLine();
Console.WriteLine(c.Join());
输出:1 2 3
1 2 3
1 2 4
注意:这只能解决1-2维,但可以很容易地推广到n维。