C#扩展方法重载

3

我有两个扩展方法:

    public static string ToString(this List<object> list, char delimiter)
    {
        return ToString<object>(list, delimiter.ToString());
    }

    public static string ToString(this List<object> list, string delimiter)
    {
        return ToString<object>(list, delimiter);
    }

当我使用这个时:
    char delimiter = ' ';
    return tokens.ToString(delimiter);

无法生效。代码完成列表中也没有char溢出。有人能告诉我如何使它有效吗?

编辑

我不小心忘记提到实际上有3个扩展方法,第三个是:

    public static string ToString<T>(this List<T> list, string delimiter)
    {
        if (list.Count > 0)
        {
            string s = list[0].ToString();

            for (int i = 1; i < list.Count; i++)
                s += delimiter + list[i].ToString();

            return s;
        }

        return "";
    }

你的 ToString 方法是不是在无限递归调用自身啊? - Asik
tokens变量的类型是什么? - Ivo
1
最后一个ToString应该使用StringBuilder而不是将列表项附加到本地字符串。 - Mike Corcoran
@MikeCorcoran 实际上应该使用 string.Join... 如果你已经有了某种类型的 IEnumerable 的所有子字符串,那么它显然和 StringBuilder 一样快。 - SimpleVar
@Thick_propheT string.Join有时实际上使用String Builder,在它不被优化的情况下,但这不会影响性能。一般来说,它只能等于或优于String Builder,因此在可能的情况下最好使用它。 - SimpleVar
显示剩余7条评论
2个回答

10

将扩展方法所在的类添加为引用:

using MyApplicationNamespace.ToStringExtensionClass;

Visual Studio / ReSharper并不会自动添加引用,只是因为该方法已被识别,只是与特定的签名不同而已。

此外,如果没有具有泛型参数的第三个扩展方法,则您的方法本身无法编译。

它们对我来说的工作方式(编译和逻辑上):

public static string ToString(this List<object> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString(this List<object> list, string delimiter)
{
    return string.Join(delimiter, list);
}

然后使用:

var list = new List<int> { 1, 2, 3, 4, 5 };
var str = list.Cast<object>().ToList().ToString(' ');
如果您想避免强制类型转换并使方法更加通用,请将它们更改为:
public static string ToString<T>(this List<T> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString<T>(this List<T> list, string delimiter)
{
    return string.Join(delimiter, list);
}

然后使用起来会更加简洁:

var list = new List<int> { 1, 2, 3, 4, 5 };
var str = list.ToString(' ');

编辑

在你的编辑后,我更好地理解了你的问题。 你应该放弃非泛型方法,并拥有可接受 char 类型的泛型重载。

public static string ToString<T>(this List<T> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString<T>(this List<T> list, string delimiter)
{
    ...
}

此外,你试图实现的逻辑可以轻松地通过以下方式实现:

string.Join(delimiter, list);

你基本上可以删除所有这些方法,只需使用它即可,除非你真的希望将其作为列表的扩展方法。


你说得对,我尝试了:return ListExtension.ToString(new List<object>(), delimiter); 然后它完美无缺 XD - Thick_propheT
@Thick_propheT 这将创建一个新的空列表... 你确定这是你使用的代码吗? - SimpleVar
哦不,这绝对不是我需要的,我只是想尝试看看需要满足Visual Studio的条件是什么。 - Thick_propheT
@Thick_propheT 哦,我明白了,太好了 :). 我敢打赌编译器告诉你它找不到符合参数的重载。这应该让你意识到有些地方出了问题 - 总是仔细阅读错误信息。 - SimpleVar
除非你真的想要将其作为列表的扩展方法。是的,我正在尝试使其适用于列表。 - Thick_propheT
显示剩余2条评论

1

我认为你的问题在于你为泛型List指定了对象类型,而没有将其定义为泛型方法。

尝试定义以下内容,看看是否有效:

public static string ToString<T>(this List<T> list, char delimiter) 
{ 
    return ToString<T>(list, delimiter.ToString()); 
} 

public static string ToString<T>(this List<T> list, string delimiter) 
{ 
    return String.join(list, delimiter); 
} 

你原来的字符串分隔函数只是在调用自身,所以你需要将你的ToString<T>(this List<T> list, string delimiter)改为像String.join这样有用的函数。


这将导致无尽且无用的递归。 - SimpleVar
1
哈哈,是的,我现在明白了。实际上,我并不知道原帖作者在字符串扩展方法中尝试什么。我猜这就是为什么他们称之为stackoverflow的原因。 - nvuono
他需要一个字符串,但使用列表和分隔符有点限制了选择。 - SimpleVar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接