2010-02-02 104 views
1

我已经读过ToString()使用反射(虽然它应该只是在它所调用的对象周围加上引号,所以我不知道它在哪里/为什么会使用反射)。有没有这方面的证据?是否有任何性能损失调用.ToString()(也许我应该调用Convert.ToString()?)?调用ToString()陷阱

+3

“将引号放在要调用的对象周围”?你是什​​么意思...我觉得这是一个错误的概念... – Romain 2010-02-02 15:54:33

+0

我认为他的意思是,如果你有一个对象叫杜卡,你有杜卡D =新杜卡(); d.ToString()会返回'duka' – taylonr 2010-02-02 15:56:09

+0

@taylonr:如果是这样的话,它肯定会*需要反射。 – 2010-02-02 16:00:53

回答

4

如果不重写ToString()方法,你最终调用Object.ToString(),它的实现看起来是这样的:

public virtual string ToString() 
{ 
    return this.GetType().ToString(); 
} 

[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical] 
public extern Type GetType(); 

并不是简单地“把周围的物体引号的方法它被称为上”。为了实现这一结果,必须反思得到的运行时类型信息,并致电ToString()上,这又看起来是这样的:

public override string ToString() 
{ 
    return ("Type: " + this.Name); 
} 

每当你经过思考的东西有一点性能的惩罚,但在这种情况下,可能不是真正重要的一个 - 除非你是在一个非常紧密,非常大的循环内进行的。

您是否看到性能问题?你试图完成什么,导致你想打电话给Object.ToString(),而不是调用你提供的覆盖版本?

+0

谢谢。好的细节在你的答案+1 – duka 2010-02-02 16:48:07

+0

顺便说一句,这只是一个理论问题,没有用例。 – duka 2010-02-03 17:46:49

3

我认为,如果你不覆盖ToString(),它是最终使用反射。

如果您有:

public class SomeObject 
{ 
    public void SomeMethod(); 
} 

void program 
{ 
    SomeObject o = new SomeObject(); 
    Console.WriteLine(o.ToString()); 
} 

你将不得不使用反射来知道是什么类型的对象O的。 现在,如果您重写ToString(),您应该这样做以获得有意义的字符串表示形式,那么您编写的代码将直接被调用,而不会反射。

+8

实际上,默认实现不使用反射。它调用标记为InternalCall的GetType(),例如直接构建到CLR中的功能。因此,即使该代码路径不应该达到任何基于反射的性能损失。 – 2010-02-02 16:01:31