当对象确实是字符串时,将对象转换为String


74

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

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

另一个是:

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

我对两者之间的区别感兴趣?第一个更有效率吗?(这只是一种推测,在我看来,ToString()方法是通过某种循环机制实现的,在这种循环机制下,将其强制转换“可以”更快,但这只是我的一种“胆量”)。

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

谁能为我解决这个问题?


4
我知道您提到Object是一个字符串,但是如果您不确定返回的对象是否为null,也可以使用“ Convert.ToString(DataRowObject [” name“]);”“进行转换 如果对象为null,则具有返回空字符串(string.empty)的额外好处,以避免任何null引用异常。
n00b

Answers:


54

两者有不同的用途。任何对象的ToString方法都应该返回该对象的字符串表示形式。强制转换非常不同,正如前面所说,关键字“ as”执行条件转换。“ as”关键字基本上说“如果该对象是这种类型,请给我对该类型的引用”,而ToString说“让我对该对象的字符串表示形式”。在某些情况下,结果可能是相同的,但不应将两者视为可互换,因为正如我所说,它们的存在目的不同。如果您打算转换,则应始终使用转换,而不是ToString。

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

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


因此,如果我正确理解这一点。.ToString将始终返回对象的字符串。如果无法将其作为字符串返回,则转换会失败吗?
DaImTo

1
@DaImTo:将对象从类型A成功转换为类型B(如果强制转换)时,将有一个新对象,您可以再次将其转换回类型A。投射并不是改变他们(核心)的身份,而是改变他们的外表。在通常情况下,转换是单程票。它使一个新对象(仅)代表旧对象。例如:当学生对象st转换为String()时,它将是一个字符串,类似于student:@ 1343; 43234。您认为您可以将其转变为具有领域价值的学生吗?
Andiana '16

@Andiana在C#的参考考试书中说:“在创建自己的类型时,您可以重写ToString以返回对象的字符串表示形式。如有必要,您可以创建一个Parse和TryParse方法,将字符串转换回原始形式。需要实现IFormattable接口,以便Convert类可以使用您的对象。” 您能否根据您先前所说的进行解释。谢谢
Ashraf Alshahawy

字符串名称= DataRowObject [“ name”]是否为字符串;工作?只是好奇...
杰克·格里芬

30

如果您知道它是a,String则一定要将其转换为a String。强制转换对象比调用虚拟方法要快。

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

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

BenchmarkHelper像这样使用Jon Skeet :

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()


1
@安德鲁:你有基准吗?它可能已经改变了,但是上次进行基准测试时,我发现虚拟方法实际上更快。我没想到会这样,但是确实如此。
乔恩·斯基特

@Jon-不,我没有!我将必须检查一下以确保。
Andrew Hare

1
@ AndrewHare- Jon的链接指向了505
TheGeekZn,2014年

16

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

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

public override string ToString()
{
    return this;
}

5

向下转换是一个相对较慢的操作,因为CLR必须执行各种运行时类型检查。然而,在此特定情形铸造string比调用更合适ToString()的一致性的缘故(你不能叫ToInt32object,而是投它int)和maintanability。


它可能没有您想的那么慢-请参阅我的回答。
Andrew Hare

5

我想再发表一则评论

如果要使用强制转换:string name =(string)DataRowObject [“ name”],则将发生异常:如果记录在数据库表的值为空。

在这种情况下,您必须使用:字符串名称= DataRowObject [“名称”] .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";

}

3

对于数据对象,建议您像下面的代码一样使用“ 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";

2

在这种情况下:

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

因为它是a string,所以我认为ToString()字符串对象的方法很简单:

return this;

因此恕我直言,没有性能损失。

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


我认为DataRowObject不了解类型,并将所有内容存储为Objects,因此它绝对不像返回此对象那样简单。
martijn_himself

3
@martjin_himself欢迎来到“对象定向”世界,让我为您介绍一个新朋友:多态。
fortran

@fortran您介意吗?我知道一切都是对象,并且多态性使您可以将字符串当作对象一样对待,但是这里无关紧要,除非我遗漏了什么?欢呼声
martijn_himself

@dfa对不起,我想说的是它不是存储为字符串,如果它们听起来有点刺耳,我希望我可以编辑评论:)
martijn_himself 2009年

1

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

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


1

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


使用“ Convert.ToString”还有一个好处,那就是您可以传递空值而不会引发异常。链接
雷米
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.