从设计角度来看,我想知道.NET的创建者为什么选择了System.Object.GetType()而不是一个System.Object.Type只读属性。
这只是一个(非常微小的)设计缺陷,还是有些原理在其中?欢迎任何解释。
如果你在反编译器Reflector中查看GetType()的声明,你会发现这个:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
attribute 和 extern 这样的组合意味着该方法实际上是在 .NET 运行时内部的未托管代码中实现的。 这篇文章 中的 GUID 问题进一步阐述了这一点。他们显然之所以这样做是出于性能原因,经过确定,如果在较低的级别处理,找出 Type 会更快。
这导致了两个不实现 GetType 方法作为属性的原因。首先,无法像方法一样定义属性 extern,因此需要在本机 .NET 代码中处理它。其次,即使您可以将它们定义为 extern,从属性内部执行不安全的、未托管的调用肯定会违反属性用法指南,因为更难以保证没有副作用。
public extern Type Type { [MethodImplAttribute(MethodImplOptions.InternalCall)]get; }
- Mr AndersonDoStuff(obj.Type);
....
DoStuff(obj.Type);
etc.
instead of
Type type = obj.GetType();
DoStuff(type);
....
DoStuff(type);
这样做不是很优秀,所以他们把它作为一种方法来建议尽量少用。
Type
和MemberInfo
派生对象需要大量内存。因此,如果应用程序持有太多这些对象……,应用程序的内存消耗会急剧增加,对应用程序的性能产生不利影响。在内部,CLR有一种更紧凑的方式来表示这些信息。CLR仅为我们的应用程序创建这些对象,以使开发人员更容易使用。”(还有更多内容,但现在就让它们足够了。) - stakx - no longer contributing据我所了解,通常认为将内部字段或值通过属性公开是良好的实践,而其他可能需要更多时间或其他资源来计算的值则应该使用方法来公开。
只有微软能回答这个问题,但我认为这是因为.NET框架中的几个类创建了自己重载版本的GetType()方法,并增加了额外的参数。如果它是一个属性,它们无法使用相同的名称(因为属性没有参数)。
这只是我的一些想法。
有点晚回复,但在寻找相关内容时遇到了这个问题。
GetType 可能会抛出异常。框架指南说明属性不应该引发异常。这是将其作为方法而不是属性的另一个原因。
Nullable<T>
上调用 GetType()
,并且 HasValue
字段为 null,则会引发异常。当 GetType()
被发明时(因为 Nullable<T>
不存在),这不是问题,但如果 GetType
是一个属性,那么这将是一种奇怪的行为(因为 Nullable<T>
实际上从来不是 null,并且具有像 HasValue
这样总是正常工作的属性)。 - supercatHasValue
字段为false的那个。两个字段都不能为null。 - supercatNullReferenceException
的其他实例吗?与其定义仅适用于一个方法的规则并说行为是“规则”的结果而不是方法,我认为将行为与方法相关联更有帮助。 - supercat
GetType
可以重载(由 Philippe 提出),2)因为属性不能抛出异常(由 Mikko 提出),3)因为属性不能太昂贵(由 Joel 提出),4)出于性能考虑(由 Martin 提出)。对他们所有人都加一分。 - nawfalNullable<T>
。有趣的是,当HasValue
为false
时,调用Value
属性会引发异常。 - Mr Anderson