C# 是否有理由这样做类型比较?

C# 是否有理由这样做类型比较?,c#,equals,typeof,C#,Equals,Typeof,我习惯于看到像这样的旧代码 if (true) { ... } 直觉上很明显,有人在做出改变时要么懒惰,要么过于谨慎。今天我偶然看到了这段代码,我很好奇这样进行类型比较是否有功能上的区别: private static bool logField(Type t, string fieldname) { if (t.ToString() == typeof (Property).ToString()) { ... } return true

我习惯于看到像这样的旧代码

if (true)
{
    ...
}
直觉上很明显,有人在做出改变时要么懒惰,要么过于谨慎。今天我偶然看到了这段代码,我很好奇这样进行类型比较是否有功能上的区别:

private static bool logField(Type t, string fieldname)
{
    if (t.ToString() == typeof (Property).ToString())
    {
        ...
    }
    return true;
}
private static bool logField(Type t, string fieldname)
{
    if (t == typeof (Property))
    {
        ...
    }
    return true;
}
这样做:

private static bool logField(Type t, string fieldname)
{
    if (t.ToString() == typeof (Property).ToString())
    {
        ...
    }
    return true;
}
private static bool logField(Type t, string fieldname)
{
    if (t == typeof (Property))
    {
        ...
    }
    return true;
}

我想不出任何好的理由


事实上,如果
t
为空,则前者将抛出。

我会说这通常是懒惰,但可能不是。例如,可以在同一有效文件中有两种特性类型,但副本不同。如果
typeof(Property)
从一个文件加载,但
t
从另一个文件加载,则替换者会说它们不同,但原始代码会比较说它们相同


这绝对是一个边缘的情况,一个你通常想避免在第一位。。。但是这是可能的。

不,获取相同类型的两个实例的type对象将始终返回对内存中相同类型对象的引用。这意味着执行引用相等性检查(=)就足够了

基本上,呼吁: if(t.ToString()==typeof(Property).ToString())


将对同一对象调用ToString()两次,其中t是“属性”类型。

第一个函数比较字符串的引用,而第二个函数实际检查t是否为属性类型

第一个字符串总是“正确”的,因为两个字符串引用同一个对象,但第二个字符串是检查t是否为属性类型的正确方法

执行类型检查的一种等效且更具可读性的方法是

if (t is Property)

我想说,第一种方法可能是由不熟悉C#的人完成的,不一定是懒惰的。字符串比较在大多数情况下都有效,但以下情况除外:

  • 如果
    t
    为null,它将抛出null引用异常
  • 它不考虑名称空间

  • 我建议使用第二种情况,除非您需要使用#2 edge情况。

    我不知道有什么好的理由这样做。事实上,我认为它是一个bug,因为它至少有一个潜在的Null RealEngExchange问题。它将命名空间考虑进去。Type。ToScript包括命名空间。@乔恩,你是正确的。我被Reflector(Type.ToString不包括名称空间,但RuntimeType覆盖了该名称空间)误导了,这两个属性类型有一个非常好的观点。如果要比较类型,请直接进行,而不是通过字符串表示。如果您想比较类型名(可能是因为您给出的原因),那么就这样做。虽然if代码依赖于比较类型名,但我认为注释是正确的。我不知道在任何情况下,所涉及的DLL都会从同一AppDomain中的多个位置加载(我在不同的应用程序中遇到了这个问题)。当你说“相同的有效文件,但不同的副本”时,这就是你所指的吗?@arootbeer:这种情况通常是有人通过程序集名称加载程序集,奇怪的是,通过其路径第二次加载程序集。CLR的原因是,如果在已按名称加载程序集时按路径重新加载已加载的程序集,则必须将这些程序集及其类型视为不同的。然后,您就可以很容易地陷入一种非常混乱的情况,即有两个相同的类型,但它们被认为是不相同的。苏珊娜·库克(Suzanne Cook)早在早期就写了一大堆关于这个的博客文章,详情请参见她的博客。@Eric Lippert-我最近遇到过这个问题,当时我正在构建一个插件系统,我在两个地方有一个DLL(NServiceBus.DLL)的副本:bin文件夹(容器正确引用了它)和plugins文件夹(它被一个消息dll引用,我错误地复制了它)。当加载程序加载插件目录中的DLL时,它拾取NSB的第二个实例,因为它是引用插件程序集所在的本地实例。然后,当检查插件中的消息是否为NSB.IMessage时,它确定它们不是关联的。-因为它们是由两个独立实例定义的类型我认为这可能不会像从同一个地方显式加载同一个DLL那样奇怪,这就是我之所以提出它的原因。很高兴知道运行时为typeof()的每个实例返回相同的引用但是,正如Jon Skeet所提到的,如果从DLL的两个不同副本加载相同的类型,则运行时会认为它们是不同的类型。