2009-10-07 35 views
10

Trong ứng dụng tôi có, tôi đang thực hiện các cuộc gọi khá thường xuyên tới Convert.ChangeType để chuyển đổi giá trị thành loại được tải động.Phiên bản Convert.ChangeType nhanh hơn

Tuy nhiên, sau khi lược tả bằng ANTS, tôi thấy rằng Convert.ChangeType này dường như mất một khoảng thời gian đáng kể (do được gọi thường xuyên). Có ai có cách thay thế nhanh hơn để làm việc này không?

Tại thời điểm này, tôi có đối tượng kiểu chứa mục tiêu và string chứa giá trị.

Sau đây là mã vi phạm. Tôi đã xem xét thực hiện một tuyên bố chuyển đổi về loại (vì nó là một bộ sưu tập hạn chế của các loại) và gọi các phương pháp phân tích cú pháp, mặc dù tôi không chắc chắn hay không mà sẽ được nhanh hơn.

if(attributeRow["Value"]!=DBNull.Value) 
    sample[attr] = attr.AttributeType == typeof(Guid) 
       ? new Guid(attributeRow["Value"].ToString()) 
       : (IComparable)Convert.ChangeType(attributeRow["Value"],attr.AttributeType); 

Trả lời

9

Tôi không biết về bất kỳ chức năng nào khác trong khung chính vì thay đổi các loại khác với chức năng Convert.ChangeType (và rõ ràng là phôi).

Đối với điều này, tôi nghĩ cách duy nhất để cải thiện điều này là cuộn chức năng ChangeType của riêng bạn được tối ưu hóa cụ thể cho trường hợp cụ thể của bạn (nếu có thể).

Bạn đề cập rằng bạn đang làm việc với một số loại giới hạn, có lẽ bạn đang xử lý một Loại nhiều hơn các loại khác? Như vậy, chức năng ChangeType của bạn có thể được tối ưu hóa để thử chuyển đổi cụ thể này trước tiên và chỉ thử những người khác nếu không thực hiện được. Bạn đề cập đến việc thử một khối mã kiểu chuyển đổi và cách tiếp cận tương tự này (cố gắng sử dụng Loại thường được sử dụng đầu tiên) có thể được áp dụng cho điều đó. Cho dù nó sẽ nhanh hơn sẽ phụ thuộc vào dữ liệu của bạn mà bạn đang xử lý (và tần số/biến đổi của các loại bạn đang chuyển đổi/từ) và cách duy nhất thực sự để đo lường này là thử nó và cấu hình nó trong so sánh với phương pháp Convert.ChangeType.

Một liên kết thú vị nếu bạn đang tìm kiếm để roll-bạn-của chức năng là trên blog của Peter Johnson:

Convert.ChangeType doesn't handle nullables

Hãy chắc chắn để đọc tất cả các ý kiến ​​để bài viết cũng có.

+0

Chúng tôi sẽ xem xét một vài điều, nhưng bài đăng này khẳng định nỗi sợ của tôi rằng chúng tôi đã làm điều đó một cách tốt nhất có thể, vì vậy tôi chấp nhận câu trả lời này. – Erich

+0

Loại thay đổi được cung cấp trong liên kết hoạt động hoàn hảo! Cảm ơn! – Larry

0

Bạn có thể cuộn chức năng ChangeType của riêng bạn mà chỉ thực hiện truyền kiểu C tĩnh. Đó sẽ là cách tiếp cận của tôi.

+0

Vấn đề là nguồn là một chuỗi, không phải là một giá trị thực tế, do đó Đúc sẽ không hoạt động Tôi 'd nghi ngờ. – Erich

3

Đây là phiên bản của tôi về Loại thay đổi nhanh hơn. Tôi đoán nguyên tắc là giống như đề xuất của @CraigTP, tuy nhiên, nó sẽ chỉ làm việc cho các loại giá trị nullable.

Tôi đang căn cứ phương pháp chuyển đổi của mình trên thực tế rằng nhiều khả năng loại giá trị sẽ tương thích với loại mục tiêu là một số cách. Nhưng phương pháp này không được thiết kế để thực hiện nó được thiết kế để thuận tiện. Nó không phải cái gì tôi muốn gọi từ trong một vòng lặp chặt chẽ.

Tôi vẫn đang sử dụng ChangeType nhưng tôi cố gắng chọn không tham gia sớm nhất có thể.

public static T? ToOrDefault<T>(object value) 
    where T : struct, IConvertible 
{ 
    var x = value as T?; 
    if (x.HasValue) 
    { 
     return x; 
    } 
    if (value == null || Convert.IsDBNull(value)) 
    { 
     return null; 
    } 
    try 
    { 
     return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); 
    } 
    catch (InvalidCastException) 
    { 
    } 
    catch (FormatException) 
    { 
    } 
    catch (OverflowException) 
    { 
    } 
    catch (ArgumentException) 
    { 
    } 
    return default(T?); 
} 
+0

Bạn có thể vui lòng cho biết cách bạn sử dụng mã trên trong mã của mình không? – Naomi

+0

Vâng, hãy xem xét lớp 'DataTable', nếu bạn có giá trị ở đâu đó, tất cả chúng đều được hiển thị dưới dạng' đối tượng'', giả sử bạn biết có một số ở đâu đó, sau đó bạn nhận được giá trị như vậy: ' Bảng DataTable; int? num = ToOrDefault (table.Rows [0] [3]); 'Điều đó sẽ thành công nếu có bất kỳ cách nào để lấy số nhưng nếu không trả về null. Không ném ngoại lệ! –

+0

Phần catch'em'all của mã của bạn truyền cảm hứng cho tôi sợ hãi và khủng bố. Nếu có điều gì đó sai (ngoại lệ), bỏ qua lỗi có thể tạo ra các vấn đề toàn vẹn dữ liệu. – SandRock

0

Tôi chưa thử nghiệm nếu nhanh hơn, nhưng đây là cách thay thế cho đúc động.Đây là alsp phổ quát hơn, vì Convert.ChangeType() có một số hạn chế, như bạn đã thấy (Guids, các loại Nullable)

value = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(str); 
Các vấn đề liên quan