简体   繁体   English

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

[英]How to write overloaded generic extension methods for T[], T[][] without ambiguity?

I want to write extension methods for converting a vector and matrix into string. 我想编写用于将向量和矩阵转换为字符串的扩展方法。 I did this in the following way. 我是用以下方式做到的。

For Vector 对于矢量

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

For Matrix 对于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; }
}

Now i am using following code which causes ambiguity. 现在我使用以下代码导致歧义。

List<double[]> Patterns= GetPatterns(); 
Patterns.ToArray().GetString();

Error 错误

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

Can anyone suggest me to write these extension methods correctly. 任何人都可以建议我正确编写这些扩展方法。

Thanks in advance. 提前致谢。

您可以省略默认值,也可以在函数调用中声明T的类型

There is nothing wrong with your methods. 你的方法没有错。 It is the compiler that can't choose between them. 编译器无法在它们之间进行选择。

As you can see in the error message, the compiler could assume T to be double[] and match the first method, or double and match the second one. 正如可以在该错误消息看到,编译器可以假定Tdouble[]和匹配第一方法,或double和匹配第二个。 This will be solved by explicitly mentioning which method you want to use: 这将通过明确提到您要使用的方法来解决:

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

The compiler can't tell whether you want to call GetString<double[]> or GetString<double> because both methods fit the invocation. 编译器无法判断是否要调用GetString<double[]>GetString<double>因为两种方法都适合调用。

The easiest way to solve that is to simply change one of the names (ie GetArrayString<T> ). 解决这个问题的最简单方法是简单地更改其中一个名称(即GetArrayString<T> )。 A better solution IMO is to have only 1 method that solves both cases like this one: 更好的解决方案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);
}

Usage: 用法:

int[] a = {1, 2, 3};
int[] b = { 1, 2, 4 };
int[][] c = {a, b};

Console.WriteLine(a.Join());
Console.WriteLine();
Console.WriteLine(c.Join());

Output: 输出:

1 2 3

1 2 3
1 2 4

Note: This only solves for 1-2 dimensions, but can easily be generalized to n dimensions. 注意:这仅解决了1-2维,但可以很容易地推广到n维。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM