2009-07-23 34 views
64

Đây không thực sự là vấn đề, tuy nhiên tôi tò mò. Khi tôi lưu một chuỗi trong cho phép nói một DataRow, nó được truyền tới Object. Khi tôi muốn sử dụng nó, tôi phải bỏ nó ToString. Theo như tôi biết có một số cách để làm điều này, đầu tiên làTruyền vs Chuyển đổi đối tượng thànhString, khi đối tượng thực sự là một chuỗi

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

và một số khác là:

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

Tôi quan tâm đến sự khác biệt giữa hai là gì? Là người đầu tiên hiệu quả hơn? (Đây chỉ là một suy đoán, trong đầu ToString() phương pháp của tôi được thực hiện bởi một số cơ chế lặp mà chỉ cần đúc nó "có thể" được nhanh hơn, tuy nhiên đây chỉ là một "cảm giác ruột" tôi có).

Thậm chí còn có cách làm nhanh hơn/thanh lịch hơn nữa không?

Có ai có thể xóa điều này cho tôi không?

+3

Tôi biết bạn nói rằng đối tượng là một chuỗi, nhưng trong trường hợp bạn không chắc chắn sợ đối tượng trở về là null, bạn cũng có thể truyền bằng ứng dụng "Convert.ToString (DataRowObject [" name "]);" Điều này có thêm lợi ích của việc trả về một chuỗi rỗng (string.empty) nếu đối tượng là null, để tránh bất kỳ ngoại lệ tham chiếu null nào. – n00b

Trả lời

47

Hai mục đích dành cho các mục đích khác nhau . Phương thức ToString của bất kỳ đối tượng nào được cho là trả về một chuỗi đại diện của đối tượng đó. Việc đúc hoàn toàn khác và cụm từ 'as' chính thực hiện một dàn diễn viên có điều kiện, vì đã được nói. Từ khóa 'as' chính về cơ bản nói "cho tôi tham chiếu loại này với đối tượng đó nếu đối tượng là loại này" trong khi ToString nói "lấy cho tôi một biểu tượng chuỗi của đối tượng đó".Kết quả có thể là cùng trong một số trường hợp nhưng hai nên không bao giờ được coi là hoán đổi cho nhau bởi vì, như tôi đã nói, chúng tồn tại cho mục đích khác nhau. Nếu ý định của bạn là truyền thì bạn phải luôn sử dụng một diễn viên, KHÔNG TẮT.

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

cũng http://bytes.com/groups/net-c/225365-tostring-string-cast

+0

Vì vậy, nếu tôi hiểu chính xác điều này. . ToString sẽ luôn trả về một chuỗi đối tượng. Trong khi đúc sẽ thất bại nếu nó không thể được trả về như một chuỗi? – DaImTo

+1

@DaImTo: Khi bạn truyền một đối tượng từ loại A đến loại B (nếu đúc) thành công, bạn sẽ có một đối tượng mới mà bạn có thể truyền lại thành loại A. Việc đúc không thay đổi họ là ai (cốt lõi), nhưng thay đổi họ sẽ trông như thế nào. Chuyển đổi, trong trường hợp phổ biến, là một vé một chiều. Nó làm cho một đối tượng mới (chỉ) đại diện cho đối tượng cũ. Ví dụ: một đối tượng sinh viên st khi chuyển đổi toString() sẽ là một chuỗi giống như sinh viên: @ 1343; 43234. bạn có nghĩ rằng bạn có thể biến nó trở lại thành một sinh viên có giá trị trường? – Andiana

+0

@Andiana Trong sách thi Ref cho C# nó nói "Khi tạo các loại của riêng bạn, bạn có thể ghi đè ToString để trả về một chuỗi đại diện của đối tượng của bạn. Nếu cần, bạn có thể tạo một phương thức Parse và TryParse để chuyển đổi chuỗi đối tượng ban đầu. Cần thực hiện giao diện IFormattable để đối tượng của bạn có thể được sử dụng bởi lớp Chuyển đổi. " Bạn có thể giải thích nó theo ánh sáng của những gì bạn đã nói trước đó không. Cảm ơn bạn –

27

Nếu bạn biết đó là String thì bằng mọi cách hãy truyền nó đến String. Đúc đối tượng của bạn sẽ nhanh hơn gọi một phương thức ảo.

Edit: Đây là kết quả của một số điểm chuẩn:

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

tôi đã sử dụng Jon Skeet BenchmarkHelper như thế này:

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

Vì vậy, nó dường như đúc mà là trong thực tế hơi nhanh hơn hơn gọi số ToString().

+1

@Andrew: Bạn đã đo điểm chuẩn đó chưa? Nó cũng có thể đã thay đổi, nhưng lần cuối tôi chuẩn bị nó tôi thấy rằng phương pháp ảo thực sự nhanh hơn. Tôi đã không mong đợi nó được, nhưng nó đã được. –

+0

@Jon - Không, tôi không có!Tôi sẽ phải kiểm tra để đảm bảo. –

+1

@ AndrewHare- liên kết của Jon dẫn đến 505 – TheGeekZn

16

Về cơ bản trong trường hợp của bạn, tốt hơn là bỏ kiểu truyền vì .ToString() có thể ẩn các lỗi. Ví dụ: lược đồ cơ sở dữ liệu của bạn đã thay đổi và tên không còn thuộc loại chuỗi nhưng với .ToString(), mã của bạn vẫn hoạt động. Vì vậy, trong trường hợp này, tốt hơn là sử dụng kiểu đúc.

Đây là thực hiện String.ToString() - không có gì đặc biệt =)

public override string ToString() 
{ 
    return this; 
} 
+5

+1 để giải mã String.ToString() –

5

downcasting là một hoạt động tương đối chậm kể từ khi CLR có để thực hiện khác nhau thời gian chạy kiểu kiểm tra. Tuy nhiên, trong trường hợp cụ thể này đúc thành string phù hợp hơn gọi số ToString() vì mục đích nhất quán (bạn không thể gọi số ToInt32 trên object, nhưng truyền đến int) và khả năng bảo trì.

+0

Nó có thể không chậm như bạn nghĩ - hãy xem câu trả lời của tôi. –

2

thấy Trong trường hợp này:

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

vì nó là một string, tôi nghĩ rằng phương pháp ToString() của một đối tượng chuỗi là đơn giản như:

return this; 

vì vậy IMHO không có hình phạt về hiệu suất.

PS Tôi là một lập trình viên Java, vì vậy anwser đây chỉ là phỏng đoán.

+0

Tôi nghĩ DataRowObject không có kiến ​​thức về các loại và lưu trữ mọi thứ dưới dạng Đối tượng, vì vậy nó chắc chắn không đơn giản như trả lại điều này. –

+3

@martjin_himself chào mừng bạn đến với thế giới của Object Orientation, hãy để tôi giới thiệu cho bạn một người bạn mới: Polymorphism. – fortran

+0

@fortran bạn có phiền không? Tôi biết tất cả mọi thứ là một đối tượng và đa hình cho phép bạn đối xử với một chuỗi như thể nó là một đối tượng, tuy nhiên đó là không thích hợp ở đây, trừ khi tôi đang thiếu một cái gì đó? chúc mừng –

1

ToString() không thực hiện diễn viên theo mặc định. Mục đích của nó là trả về một chuỗi đại diện cho loại (ví dụ: "System.Object").

Nếu bạn muốn tránh truyền, bạn có thể thử suy nghĩ về triển khai được đánh máy mạnh (ví dụ như sử dụng Generics) và tránh DataRowObject hoàn toàn.

2

Đối với đối tượng dữ liệu, tôi đề nghị bạn sử dụng "như" keyword như đoạn mã sau.

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

Vui lòng kiểm tra trước khi bạn sử dụng giá trị.

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

đây có phải là phiên bản giống nhau hơn không: 'string name = (hàng ["tên"] dưới dạng chuỗi) ?? "mặc định"; ' –

4

Tôi muốn làm thêm một bình luận

Nếu bạn đang sử dụng đúc: string name = (string) DataRowObject [ "name"] bạn sẽ nhận được một ngoại lệ: Không thể bỏ đối tượng của gõ 'System.DBNull' để gõ'System.String 'trong trường hợp nếu bản ghi trong bảng cơ sở dữ liệu có giá trị null.

Trong kịch bản này, bạn phải sử dụng:. String name = DataRowObject [ "name"] ToString() hoặc

Bạn cần phải kiểm tra các giá trị null như

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"; 

} 
0

Tôi biết bạn nói rằng đối tượng là một chuỗi, nhưng trong trường hợp bạn sợ rằng đối tượng trả về là null, bạn cũng có thể truyền bằng cách sử dụng "Convert.ToString (DataRowObject [" name "]);" Điều này có thêm lợi ích của việc trả về một chuỗi rỗng (string.empty) nếu đối tượng là null, để tránh bất kỳ trường hợp ngoại lệ tham chiếu null nào (trừ khi tất nhiên bạn muốn một ngoại lệ được ném trong trường hợp này).

+0

Có một lợi ích bổ sung khi sử dụng" Convert.ToString "và đó là bạn có thể chuyển một giá trị rỗng mà không có ngoại lệ được ném. [link] (http://msdn.microsoft.com/en-us/library/astxcyeh.aspx) – Remy

Các vấn đề liên quan