如何为T [],T [] []编写重载的泛型扩展方法而没有歧义?

时间:2014-08-03 08:36:32

标签: c# generics extension-methods default-parameters

我想编写用于将向量和矩阵转换为字符串的扩展方法。我是通过以下方式做到的。

对于矢量

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; }
}

适用于Matrix

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)'    

任何人都可以建议我正确编写这些扩展方法。

提前致谢。

3 个答案:

答案 0 :(得分:4)

您可以省略默认值或在函数调用中说明T的类型

答案 1 :(得分:4)

您的方法没有任何问题。编译器无法在它们之间进行选择。

正如您在错误消息中看到的那样,编译器可以假定Tdouble[]并匹配第一种方法,或double并匹配第二种方法。这将通过明确提到您要使用的方法来解决:

Patterns.ToArray().GetString<double>();

答案 2 :(得分:0)

编译器无法判断您是否要调用GetString<double[]>GetString<double>,因为这两种方法都适合调用。

解决这个问题的最简单方法是简单地更改其中一个名称(即GetArrayString<T>)。一个更好的解决方案IMO只有一种解决这两种情况的方法:

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维。