【问题标题】:C# Extension Method OverloadC# 扩展方法重载
【发布时间】:2012-05-13 04:39:44
【问题描述】:

我有两种扩展方法:

    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 方法无限期地调用自己?
  • tokens变量的类型是什么?
  • 查看我的答案的编辑,作为您编辑的后续。
  • 最后一个 ToString 应该真正使用 StringBuilder 而不是将列表项附加到本地字符串...

标签: c# extension-methods overloading


【解决方案1】:

添加对具有扩展方法的类的引用:

using MyApplicationNamespace.ToStringExtensionClass;

VS / 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 ListExtensions.ToString(tokens, delimiter);它会显示字符重载,但由于某种原因它不喜欢标记...
  • @Thick_propheT 这可能是因为您没有使方法通用,这意味着它需要 List&lt;object&gt; - 哪些令牌不是。尝试使用答案末尾的两种通用方法。
  • 你说得对,我试过了: return ListExtension.ToString(new List(), delimiter); 110% 满意 XD
  • @Thick_propheT 这将创建一个新的空列表...您确定这是您使用的代码吗?
  • 哦,不,这绝对不是我需要的,我只是想看看如何才能满足 Visual Studio。
【解决方案2】:

我认为您的问题是您正在为泛型 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&lt;T&gt;(this List&lt;T&gt; list, string delimiter) 才能在此处执行一些有用的操作,例如 String.join

【讨论】:

  • 这将导致无穷无尽的无用递归。
  • 哈哈是的,我现在明白了。我实际上不知道原始海报在字符串扩展方法中尝试的是什么。我想他们称之为 stackoverflow 是有原因的
  • 他想要一个字符串并使用列表和分隔符的事实缩小了选择范围。
猜你喜欢
  • 2023-03-23
  • 2012-06-15
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 2015-02-26
  • 2013-04-08
  • 1970-01-01
相关资源
最近更新 更多