StringBuilder扩展追加调用解析
本文关键字:调用 追加 扩展 StringBuilder | 更新日期: 2023-09-27 18:04:02
我有一个扩展方法,将IEnumerable中的每个对象附加到StringBuilder中。它用类型参数对IEnumerable进行操作,所以我的问题是它会触发Append()调用唯一的单独类型,还是会所有作为"对象"传递并且效率低下?如果我需要的话,我会针对特殊情况扩展函数,其中StringBuilder具有对类型唯一的Append()调用,但我需要知道我是否必须这样做。
/// <summary>
/// Appends each object in the enumerable to the StringBuilder's content.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sb"></param>
/// <param name="e"></param>
/// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException"/>
public static StringBuilder AppendEach<T>(this StringBuilder sb, IEnumerable<T> e)
{
e.Do<T>(t => sb.Append(t));
return sb;
}
/// <summary>
/// Allows you to run code on each value in a collection in-line.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <param name="action"></param>
public static void Do<T>(this IEnumerable<T> e, Action<T> action)
{
foreach (T t in e) action(t);
}
不确定我使用的Do扩展是否会改变问题的结果,所以我包含了它而不是简化代码。我知道有些人会因为我在这里写"有副作用的LINQ方法"而绞死我,但这与手头的问题无关。
不,如果你的意思是"它会触发Append()调用唯一的单独的类型",它将调用Append(Object)
。
因为碰巧有争议。c#编译器必须在编译时决定使用哪个方法。这意味着所选择的方法参数不能与您放入Append(…)中的变量冲突。由于编译器在编译时不知道T是什么,它将选择Append(object)
,因为无论T是什么,它都是唯一可以工作的。
我已经模拟了这个场景:
public class C
{
public static void Show(object value)
{
"object".Dump();
}
public static void Show(int value)
{
"int".Dump();
}
public static void Show(string value)
{
"string".Dump();
}
}
public class MyClass<T>
{
public void Append(T value)
{
C.Show(value);
}
}
public void Main()
{
var c1 = new MyClass<int>();
var c2 = new MyClass<string>();
var c3 = new MyClass<object>();
c1.Append(1);
c2.Append("1");
c3.Append(2);
}
显示了3次"object"
顺便说一句。如果从类中删除对象方法,它将无法编译,因为它将无法找到合适的方法。
把它留在这里供讨论,除非有人认为可以删除它——但是这里的信息是不正确的。
<引用类>一切都不会作为"对象"传递——一切都将以T的形式传递(或者是stringbuilder调用Append()的最具体的T的超类)。如果你传入一个IEnumerable,那个enumerable中的每一项都会被传递给Append(object)覆盖,因为编译器不知道如何调用更具体的覆盖。然而,如果传入一个IEnumerable,则Append(string)将被调用,因为编译器现在对该类型有足够的了解,可以选择适当的覆盖。如果你传入一个IEnumerable,但是enumerable中的每个对象都是字符串,它仍然会调用Append(object)重写,因为类型信息丢失了。
引用类>