2009-08-26 25 views
10

Tôi đã có một tình huống mà tôi có một đối tượng kinh doanh với khoảng 15 thuộc tính của các loại khác nhau. Đối tượng kinh doanh cũng phải thực hiện một giao diện trong đó có các phương pháp sau đây:.NET: chuyển đổi so với từ điển cho các phím chuỗi

object GetFieldValue(string FieldName); 

tôi có thể thấy 2 cách thực hiện phương pháp này:

Sử dụng một câu lệnh switch:

switch (FieldName) 
{ 
    case "Field1": return this.Field1; 
    case "Field2": return this.Field2; 
    // etc. 
} 

Dùng từ điển (SortedDictionary hoặc HashTable?):

return this.AllFields[FieldName]; 

Điều gì sẽ hiệu quả hơn?

Đã thêm: Quên để nói. Phương pháp này là để hiển thị mục trong lưới. Lưới sẽ có một cột cho mỗi thuộc tính này. Sẽ thường xuyên có lưới với hơn 1000 mục trong đó. Đó là lý do tại sao tôi quan tâm đến hiệu suất.

Added 2:

Dưới đây là một ý tưởng: một cách tiếp cận lai. Tạo một từ điển tĩnh với các khóa là các tên thuộc tính và các giá trị là các chỉ mục trong mảng. Từ điển chỉ được điền một lần, khi khởi động ứng dụng. Mỗi cá thể đối tượng có một mảng. Vì vậy, tra cứu sẽ như sau:

return this.ValueArray[StaticDictionary[FieldName]]; 

Thuật toán điền từ điển có thể sử dụng phản chiếu. Sau đó, các thuộc tính sẽ được triển khai cho phù hợp:

public bool Field1 
{ 
    get 
    { 
     object o = this.ValueArray[StaticDictionary["Field1"]]; 
     return o == null ? false : (bool)o; 
    } 
    set 
    { 
     this.ValueArray[StaticDictionary["Field1"]] = value; 
    } 
} 

Ai có thể thấy bất kỳ vấn đề nào với điều này không?

Nó cũng có thể được thực hiện thêm một bước và ValueArray/StaticDictionary có thể được đặt trong một loại chung riêng biệt ValueCollection<T>, trong đó T sẽ chỉ định loại phản ánh. ValueCollection cũng sẽ xử lý trường hợp khi chưa có giá trị nào được đặt. Thuộc tính sau đó có thể được viết đơn giản như:

public bool Field1 
{ 
    get 
    { 
     return (bool)this.Values["Field1"]; 
    } 
    set 
    { 
     this.Values["Field1"] = value; 
    } 
} 

Và cuối cùng, tôi bắt đầu tự hỏi một lần nữa, nếu một câu lệnh switch đơn giản có thể không được cả hai nhanh hơn và dễ dàng hơn để duy trì ....

+0

Có lý do nào khiến bạn không ràng buộc toàn bộ đối tượng vào lưới dưới dạng datarow không? –

+0

Để nói sự thật, đó là thingy DevExpress TreeList. Nó giống như một hybrid treeview/gridview. Vì vậy, dữ liệu phải được phân cấp. Và giao diện là có để TreeList hiểu được thứ bậc. Tôi có lẽ cũng có thể dịch nó tất cả để một DataTable (nó có thể ràng buộc với điều đó quá), nhưng điều này là thoải mái hơn cho tôi để làm việc với sau đó. –

+0

Ý tôi là, tôi sẽ làm những thứ khác với cấu trúc dữ liệu này sau đó, không chỉ hiển thị nó trong lưới. –

Trả lời

21
switch:  good efficiency, least maintainable 
dictionary: good efficiency, better maintainability 
reflection: least efficient, best maintainability 

Gợi ý: bỏ qua hiệu quả và lo lắng về khả năng bảo trì, trừ khi bạn đã thực sự thử nghiệm hiệu suất và thấy rằng đó là một vấn đề.

Tôi không nói phản chiếu là lựa chọn duy nhất của bạn, chỉ cho phép bạn thêm/xóa và đổi tên thuộc tính nếu cần và không cần giữ tuyên bố chuyển đổi hoặc từ điển đồng bộ hóa.

+0

Hmm ... cũng ... ok ... –

+0

Phản ánh sẽ cho phép các thuộc tính của bạn được phát hiện tại thời gian chạy và vì vậy nếu bạn thêm/xóa hoặc đổi tên bất kỳ, bạn không cần phải viết lại bất kỳ mã nào khác (chẳng hạn như câu lệnh chuyển đổi hoặc khởi tạo từ điển). – Ash

+7

Tôi có xu hướng tìm thấy chi phí nhận thức của sự phản chiếu làm cho nó có phần ít bảo trì hơn so với cách tiếp cận từ điển dispatch-table. Mặc dù điều đó có thể chỉ vì tôi không sử dụng sự phản chiếu rất thường xuyên. :) –

7

Vì bạn đang sử dụng chuỗi Từ điển có thể sẽ nhanh hơn. Chuyển đổi về cơ bản sẽ được dịch sang một hashtable khi sử dụng chuỗi. Nhưng nếu bạn đang sử dụng ints hoặc tương tự nó được dịch sang một bảng nhảy và sẽ nhanh hơn.

thấy this answer và hỏi để biết thêm chi tiết

đặt cược tốt nhất là để cấu hình nó và tìm cho chắc chắn

0

Làm thế nào bạn nhận được giá trị của mỗi tài sản có thể sẽ có tác động ít hơn về hiệu suất tổng thể hơn cách bạn hiển thị lưới của bạn.

Để tôi cho bạn một ví dụ: giả sử bạn có thực hiện như sau:

private string _latestFieldName = string.Empty; 
private PropertyInfo _propertyInfo; 

object GetFieldValue(string FieldName) 
{ 
    if(FieldName != _latestFieldName) 
    { 
    _propertyInfo = typeof(yourTypeName).GetProperty(FieldName); 
    } 
    return _propertyInfo.GetValue(this,null); 
} 

Nếu vẽ lưới của bạn được render một hàng tại một thời gian sử dụng phản ánh nó sẽ có để có được những PropertyInfo mỗi lần duy nhất . wheras nếu bạn hiển thị cột theo cột, bạn chỉ phải lấy thuộc tínhInfo một lần cho mỗi thuộc tính và vì dự đoán chi nhánh sẽ đúng gần như mỗi khi bạn chỉ bỏ lỡ một vài chu kỳ đồng hồ trên if. Khi bạn đã có PropertyInfo rồi và bạn không cần truyền kết quả của cuộc gọi đến GetValue. bằng cách sử dụng phản ánh đến rất gần với việc sử dụng getter của một tài sản khi nói đến tốc độ.

Điểm của tôi là trước khi bạn bắt đầu tối ưu hóa sử dụng trình thu thập thông tin. (Tất nhiên nếu bạn không thể thay đổi lưới tốt bạn có thể không thực sự tối ưu hóa nó hoặc)

+0

Không, tôi không thể thay đổi lưới. :) –

0

Chuyển thực sự có 2 lợi ích so với từ điển:

  1. Bạn có thể tạo thông điệp ngoại lệ tùy chỉnh trong phần mặc định mà có thể bao gồm giá trị không hợp lệ. Trong trường hợp từ điển bạn chỉ nhận được KeyNotFoundException không chứa tên khóa.
  2. Bạn có thể xử lý các giá trị null. Từ điển không thể lưu trữ null dưới dạng khóa.
Các vấn đề liên quan