限制通用扩展方法扩展字符串

时间:2016-12-02 09:46:57

标签: c# methods extension-methods

我有一个非常通用的扩展方法来显示控制台中的任何类型的列表:

tabLayout.setTabTextColors(ContextCompat.getColorStateList(this, R.color.tab_selector));
tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.indicator));

当我有public static void ShowList<T>(this IEnumerable<T> Values) { foreach (T item in Values) { Console.WriteLine(item); } } 时,我可以使用此方法

string

但是在string text = "test"; text.ShowList(); 的情况下,它在我的应用程序中没有意义。

如何从此方法中排除string?我读过一些关于

的文章
string

3 个答案:

答案 0 :(得分:31)

这开始时有点奇怪的要求,说实话 - 如果某些内容适用于任何字符序列,那么它应该适用于字符串,的序列字符。

如果你真的想让它无法编译,你可以添加一个接受string的重载,它被标记为已废弃:

[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete(IsError = true, Message = "A string is a sequence of characters, but is not intended to be shown as a list")]
public static void ShowList(this string text)
{
    throw new NotSupportedException();
}

重载决策将选择该方法,然后它将无法编译。 EditorBrowsable属性希望从Intellisense中删除它 - 但是你必须看看它是否真的有效。 (它可能会显示另一个过载,即使不会被选中。)

另一种选择是实现ShowList<T>,就像字符串是单项列表一样:

// Specialization to avoid listing each character separately.
public static void ShowList(this string text) => new[] { text }.ShowList();

换句话说,让它调用有效,但更适当地处理它。

答案 1 :(得分:9)

您可以创建另一个特定于ShowList()的{​​{1}}重载,并将其标记为string

[Obsolete]

通过将[Obsolete("Not intended for strings", true)] public static void ShowList(this string val) { } 传递给true参数,编译器将阻止您使用该方法。

请参阅ObsoleteAttribute

答案 2 :(得分:3)

对于无声忽略,你可以使用它:

public static void ShowList<T>(this IEnumerable<T> Values)
{
    if (Values is String) return;
    // ...
}

或者如果你还要写字符串:

public static void ShowList<T>(this IEnumerable<T> Values)
{
    if (Values is String)
        Console.WriteLine(Values);
    else
        foreach (T item in Values)
        {
            Console.WriteLine(item);
        }
}