【问题标题】:Casting vs Converting an object toString, when object really is a string当对象确实是字符串时,强制转换与将对象转换为字符串
【发布时间】:2009-07-23 09:58:44
【问题描述】:

这不是一个真正的问题,但我很好奇。当我在假设 DataRow 中保存一个字符串时,它被强制转换为 Object。当我想使用它时,我必须将它转换为 ToString。据我所知有几种方法可以做到这一点,首先是

string name = (string)DataRowObject["name"]; //valid since I know it's a string

还有一个是:

string name = DataRowObject["name"].ToString();

我感兴趣的是两者之间的区别是什么?第一个效率更高吗? (这只是一种推测,在我看来,ToString() 方法是通过某种循环机制实现的,只是强制转换它“可能”会更快,但这只是我的“直觉”)。

有没有更快/更优雅的方式来做到这一点?

谁能帮我解决这个问题?

【问题讨论】:

  • 我知道你提到对象是一个字符串,但如果你不确定返回的对象是否为空,你也可以使用 "Convert.ToString(DataRowObject["name"]) ;"如果对象为空,这具有返回空字符串 (string.empty) 的额外好处,以避免任何空引用异常。

标签: c# string casting parsing


【解决方案1】:

两者是针对不同的 目的。任何的 ToString 方法 对象应该返回一个字符串 该对象的表示。铸件 完全不同,'as'键 word 执行条件转换,如 已经说过了。 'as' 关键词 基本上说“给我一个参考 这个类型到那个对象,如果那个 对象是这种类型”,而 ToString 说“给我一个字符串表示 该对象的”。结果可能是 在某些情况下相同,但两者应该 永远不会被认为是可互换的 因为,正如我所说,它们的存在是为了 不同的目的。如果你的意图 是投然后你应该总是使用 演员表,而不是 ToString。

来自http://www.codeguru.com/forum/showthread.php?t=443873

另见http://bytes.com/groups/net-c/225365-tostring-string-cast

【讨论】:

  • 所以如果我理解正确的话。 .ToString 将始终返回对象的字符串。如果不能作为字符串返回,则强制转换会失败?
  • @DaImTo:当您将对象从类型 A 转换为类型 B(如果转换)成功时,您将拥有一个新对象,您可以再次将其转换回 A 类型。选角不是改变他们是谁(核心),而是改变他们的样子。在常见的情况下,转换是一张单程票。它使一个新对象(仅)代表旧对象。例如:转换 toString() 时的学生对象 st 将是一个类似于 student:@1343;43234 的字符串。你觉得你能把它变回一个有字段值的学生吗?
  • @Andiana 在 Ref Exam book for c# 中说“创建自己的类型时,您可以重写 ToString 以返回对象的字符串表示形式。如有必要,您可以创建 Parse 和 TryParse 方法将字符串转换回原始对象。需要实现 IFormattable 接口,以便 Convert 类可以使用您的对象。你能不能根据你之前说的解释一下。谢谢
  • 将字符串名称 = DataRowObject["name"] 作为字符串;工作 ?只是好奇...
【解决方案2】:

如果您知道它是 String,那么请务必将其转换为 String。转换对象会比调用虚方法更快。

编辑:以下是一些基准测试的结果:

============ Casting vs. virtual method ============
cast 29.884 1.00
tos  33.734 1.13

我像这样使用 Jon Skeet 的 BenchmarkHelper

using System;
using BenchmarkHelper;

class Program
{
    static void Main()
    {
        Object input = "Foo";
        String output = "Foo";

        var results 
           = TestSuite.Create("Casting vs. virtual method", input, output)
            .Add(cast)
            .Add(tos)
            .RunTests()
            .ScaleByBest(ScalingMode.VaryDuration);

        results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
                results.FindBest());
    }

    static String cast(Object o)
    {
        return (String)o;
    }

    static String tos(Object o)
    {
        return o.ToString();
    }
}

所以看起来强制转换实际上比调用ToString()

【讨论】:

  • @Andrew:你有基准测试吗?它可能已经改变了,但是上次我对它进行基准测试时,我发现虚拟方法实际上更快。我没想到会这样,但确实如此。
  • @Jon - 不,我没有!我必须检查一下以确保。
  • @AndrewHare- Jon 的链接指向 505
【解决方案3】:

基本上,在您的情况下,最好保留类型转换,因为 .ToString() 可能会隐藏错误。例如,您的数据库架构已更改,名称不再是字符串类型,但使用 .ToString() 您的代码仍然有效。所以在这种情况下最好使用类型转换。

这是 String.ToString() 的实现 - 没什么特别的 =)

public override string ToString()
{
    return this;
}

【讨论】:

    【解决方案4】:

    向下转换是一个相对缓慢的操作,因为 CLR 必须执行各种运行时类型检查。但是,在这种特殊情况下,为了一致性起见,转换为string 比调用ToString() 更合适(您不能在object 上调用ToInt32,但将其转换为int)和可维护性。

    【讨论】:

    • 它可能没有你想象的那么慢——请看我的回答。
    【解决方案5】:

    我想再发表评论

    如果你要使用强制转换:string name = (string)DataRowObject["name"] 如果数据库表中的记录具有空值,您将得到一个异常:无法将“System.DBNull”类型的对象转换为“System.String”类型。

    在这种情况下,您必须使用:string name = DataRowObject["name"].ToString() 或

    你必须检查空值,比如

    if(!string.IsNullOrEmpty(DataRowObject["name"].ToString()))
    {
    string name = (string)DataRowObject["name"];
    }
    else
    {
    //i.e Write error to the log file
    string error = "The database table has a null value";
    
    }
    

    【讨论】:

      【解决方案6】:

      对于数据对象,我建议您使用“as”关键字,如以下代码。

      string name = DataRowObject["name"] as string;
      

      使用值前请检查。

      if(name != null)
      {
          // statement for empty string or it has value
      }
      else
      {
          // statement for no data in this object.    
      }
      

      【讨论】:

      • 这会是一个更简洁的版本吗:string name = (row["name"] as string) ?? "default";
      【解决方案7】:

      在这种情况下:

      string name = DataRowObject["name"].ToString();
      

      既然是string,我觉得字符串对象的ToString()方法很简单:

      return this;
      

      所以恕我直言,没有性能损失。

      PS 我是一名 Java 程序员,所以这个答案只是一个猜测。

      【讨论】:

      • 我觉得DataRowObject对类型一无所知,把一切都存储为Objects,所以肯定没有return this那么简单。
      • @martjin_himself 欢迎来到面向对象的世界,让我给你介绍一个新朋友:多态。
      • @fortran 您介意详细说明一下吗?我知道一切都是对象,多态性允许您将字符串视为对象,但这在这里无关紧要,除非我遗漏了什么?干杯
      • @dfa 抱歉,我的意思是它没有存储为字符串,如果它们听起来有点刺耳,我希望我可以编辑 cmets :)
      【解决方案8】:

      ToString() 默认情况下不执行强制转换。它的目的是返回一个表示类型的字符串(例如“System.Object”)。

      如果您想避免强制转换,您可以尝试考虑一个强类型的实现(例如,使用泛型)并完全避免 DataRowObject。

      【讨论】:

        【解决方案9】:

        我知道您提到 Object 是一个字符串,但如果您担心返回的对象为 null,您也可以使用 "Convert.ToString(DataRowObject["name"]);" 进行转换如果对象为 null,这具有返回空字符串 (string.empty) 的额外好处,以避免任何 null 引用异常(当然,除非您希望在这种情况下抛出异常)。

        【讨论】:

        • 使用“Convert.ToString”还有一个额外的好处,那就是您可以传入一个空值而不会引发异常。 link
        猜你喜欢
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 2014-01-14
        • 2011-08-02
        • 2016-06-10
        相关资源
        最近更新 更多