限制通用扩展方法扩展字符串
Restrict generic extension method from extending strings
我有一个非常通用的扩展方法来在控制台中显示任何类型的列表:
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
?我读过一些关于
ShowList<T>(this IEnumerable<T> Values): Where != string //doesn't work
您可以创建另一个特定于 string
的 ShowList()
重载并将其标记为 [Obsolete]
:
[Obsolete("Not intended for strings", true)]
public static void ShowList(this string val)
{
}
通过将 true
传递给 IsError
参数,编译器将阻止您使用该方法。
老实说,开始时这感觉有点奇怪 - 如果某些东西应该适用于任何字符序列,那么它应该适用于字符串,是 一个字符序列。
如果你真的想让它编译失败,你可以添加一个重载接受 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();
换句话说,使调用有效,但更适当地处理它。
对于静默忽略你可以使用这个:
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);
}
}
我有一个非常通用的扩展方法来在控制台中显示任何类型的列表:
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
?我读过一些关于
ShowList<T>(this IEnumerable<T> Values): Where != string //doesn't work
您可以创建另一个特定于 string
的 ShowList()
重载并将其标记为 [Obsolete]
:
[Obsolete("Not intended for strings", true)]
public static void ShowList(this string val)
{
}
通过将 true
传递给 IsError
参数,编译器将阻止您使用该方法。
老实说,开始时这感觉有点奇怪 - 如果某些东西应该适用于任何字符序列,那么它应该适用于字符串,是 一个字符序列。
如果你真的想让它编译失败,你可以添加一个重载接受 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();
换句话说,使调用有效,但更适当地处理它。
对于静默忽略你可以使用这个:
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);
}
}