草庐IT

c# - 这段代码能正确判断两种类型是否相等吗?

coder 2024-05-22 原文

我对 System.Type 和 .NET 中的实际类类型(如 ObjectXmlDocument)有点迷糊。 . 此代码能否正确确定特定对象的类型是否等于我指定的类?

' Given "myObject" (unknown type), and some class type (let's say "MyClass")...

If myObject.GetType.Equals(MyClass)

If TypeOf(myObject) Is MyClass

If myObject.GetType() Is MyClass

哪个是正确的?

如果您可以提供一些关于什么是类标识符与什么是 System.Type 的信息,则加分。 :)

注意:这里使用的语言无所谓,VB.NET或者C#都可以,上面的代码是伪代码。

最佳答案

首先让我们看看您给出的三个选项:

If myObject.GetType.Equals(MyClass)

这可能会导致错误,因为 equals 需要一个 System.Type,而不是一个类。类定义不是 System.Type,但您可以使用 typeof 运算符检索它。所以你可以执行 instance.Equals(typeof(MyClass)),如果对象属于给定类,它会返回 true。

If TypeOf(myObject) Is MyClass

相反,您不能对实例使用 typeof,只能对类使用,所以上面的代码会失败。此外,is 运算符会自动检查类型,因此您在使用它时不能执行 typeofGetType。您应该使用 if myObject is MyClass,如果 myObject 可以转换为 MyClass,它将返回 true。这不同于说它是该类型的实例,因为它可能是 myObject 是从 MyClass 继承的类的实例。

If myObject.GetType() Is MyClass

同样,is 运算符已经检查了两个操作数的类型,因此您应该使用 if myObject is MyClass


综上所述,我想解释一下类型系统背后的“理论”。我不是专家,所以我给你一个更实际的解释:

  • 类定义标签(如 MyClass)不是 System.Type。 System.Type 是由 CLR 生成的元数据类,用于表示标签定义的类型。要检索与某个类定义标签相关的 System.Type,请使用 typeof 运算符,如下所示:

    System.Type MyClassType = typeof(MyClass);
    
  • 在对象实例上,您可以通过调用方法 GetType() 来检索 System.Type 元数据。它将为您提供与表示实际实例的类相关的 System.Type 实例。这意味着,如果编译器将您的对象视为接口(interface)或基类,.GetType() 仍会为您提供该实例的派生程度最高的类型。

  • 您可以比较 System.Type 以检查两个对象是否是同一类的实例,但同样要注意您的实例可能是更派生的类型;相等性会失败(派生程度高的类的 System.Type 与派生程度低的类的不同)。

  • 如果需要考虑继承,可以使用方法IsAssignableFrom ,像这样:

    BaseClass instance = new DerivedClass();
    
    System.Type type = instance.GetType();
    
    if ((typeof(BaseClass)).IsAssignableFrom(type))    // returns true
    {
    }
    
  • C# 和 VB.Net 为您提供了两个运算符,使您能够即时进行类型检查,isasis 进行自动类型检索,优于自己获取 System.Type。它也解释了继承:

    DerivedClass instance = new DerivedClass();
    
    System.Type type = instance.GetType();
    
    if (instance is BaseClass)    // returns true
    {
    }
    
  • 如果您需要检查类型转换对象使用as:

    DerivedClassinstance = new DerivedClass();
    
    System.Type type = instance.GetType();
    
    AnotherClass another = instance as AnotherClass;
    
    if (another == null)    // returns true
    {
        // Do proper error treatment... throw an exception or something
    }
    

    不能as 做的是不执行正确的结果检查;问题是,如果您不检查它是否为 null 并使用它,您将得到一个 NullReferenceException,这将隐藏正确的问题(转换失败)。如果您确定可以进行强制转换,则使用显式强制转换:

    DerivedClassinstance = new DerivedClass();
    
    System.Type type = instance.GetType();
    
    AnotherClass another = (AnotherClass)instance; // throws
    

    这将抛出一个InvalidCastException,因此代码将更容易调试。

关于c# - 这段代码能正确判断两种类型是否相等吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6073698/

有关c# - 这段代码能正确判断两种类型是否相等吗?的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  4. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  5. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  6. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  7. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  8. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  9. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

  10. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

随机推荐