2009-02-11 21 views

Trả lời

3

Tôi không nghĩ có lý do chính đáng nào. Bất kỳ việc triển khai nào của GetHashCode phải đủ nhanh để đưa vào một thuộc tính. Điều đó nói rằng, có plenty of design flaws trong khuôn khổ .Net, một số nhỏ, một số nghiêm trọng. Điều này có vẻ như một nhỏ.

+10

Dựa trên các nguyên tắc được chỉ định trong Hướng dẫn thiết kế khung, nếu tính toán là "đắt" thì đó không phải là một phương pháp. Kể từ khi tính toán hashcode là một ẩn hoàn toàn cho các đối tượng tùy chỉnh như xa như khung là có liên quan nó tốt hơn như là một chức năng. –

19

Có thể bởi vì nó yêu cầu tính toán và hiển thị nó như một sự thích hợp có thể ngụ ý rằng mã băm đã có sẵn miễn phí.

Edit: Hướng dẫn về điều này: Properties versus Methods

"Các hoạt động là đủ đắt tiền mà bạn muốn giao tiếp với người dùng rằng họ nên xem xét bộ nhớ đệm kết quả."

Có lẽ GetHashCode đủ tốn kém trong một số trường hợp.

+0

Cảm ơn, có hướng dẫn không có tính chất yêu cầu tính toán không? Lý do tôi hỏi là, tôi đã thấy rất nhiều tính toán khi bạn truy cập vào tài sản. –

+1

@Janan, đôi khi nó có thể chậm để tạo ra một Hashcode tốt –

0

tính chỉ nên được sử dụng nếu việc tính toán phía sau họ là thực sự nhanh hay cache

bên cạnh hầu hết thời gian logic duy nhất trong tính nên xác nhận

-2

Bạn phải nhớ rằng .NET Framework là được thiết kế để truy cập bằng nhiều ngôn ngữ khác nhau.

Về lý thuyết, bạn có thể tạo trình biên dịch không có giá trị ghi đè chính xác. Trong khi đó sẽ làm cho một trình biên dịch khá crappy, nó sẽ không nhất thiết phải là bất hợp pháp. (Ghi nhớ các thuộc tính chỉ là các phương thức có một số dữ liệu meta)

+1

Bạn cũng có thể tạo một trình biên dịch không thể ghi đè lên các phương thức. Và nhiều thứ khác.NET giao diện yêu cầu overring một tài sản. – MichaelGG

+1

Rất nhiều giao diện yêu cầu ghi đè thuộc tính, nhưng Object là ông nội của mọi thứ, tại sao không giữ nó đơn giản? – Guvante

1

Bên cạnh đó thuộc tính không có gì khác ngoài phương thức getter và phương thức setter, từ góc độ thiết kế, thuộc tính sẽ không bao giờ chứa bất kỳ tính toán nào khác ngoài việc khởi tạo hoặc xác nhận, ví dụ:

private object _obj; 
public object Obj 
{ 
    get 
    { 
    if(_obj == null) 
    { 
     _obj = new object(); 
    } 
    return _obj; 
    } 
    set 
    { 
    if(value == badvalue) 
    { 
     throw new ArgumentException("value"); 
    } 
    _obj = value; 
    } 
} 

GetHashCode() không chứa tính toán rộng rãi, nhưng nó có thể chứa các hoạt động dài như vậy (đây là lý do tại sao phương pháp của nó thay thế) của một tài sản.

2

Thường thì nó không thể định nghĩa một HashCode cho một lớp học mà làm cho từ:

ví dụ các đối tượng của lớp học không có khái niệm được xác định rõ ràng là danh tính.

Do đó, phương pháp GetHashCode() sẽ ném NotImplementedException. Tất nhiên điều này sẽ xảy ra nếu HashCode là một thuộc tính, vì hầu hết mọi người (và các trình gỡ rối) giả sử nó luôn hợp lệ để lấy giá trị của một thuộc tính

+1

Gần như tất cả các đối tượng lớp thường có ngữ nghĩa tham chiếu hoặc ngữ nghĩa giá trị không thay đổi. Đối tượng với ngữ nghĩa tham chiếu có khái niệm nhận dạng rõ ràng (đối tượng X và đối tượng Y bằng nhau nếu và chỉ khi X và Y tham chiếu đến cùng một đối tượng). Các đối tượng với ngữ nghĩa giá trị bất biến có khái niệm nhận dạng rõ ràng (đối tượng X và đối tượng Y bằng nhau nếu chúng giữ các giá trị bằng nhau). Những loại đối tượng nào sẽ không có khái niệm nhận dạng rõ ràng? – supercat

+0

@supercat, Bằng sẽ chỉ trả về true cho đối tượng có cùng HashCode, tuy nhiên thường tôi thấy phương thức equals được xác định chỉ để sử dụng các kiểm tra đơn vị trên obejct không phải là bất biến. Vì vậy, để ngăn chặn các cảnh báo từ trình biên dịch, GetHashCode() phải được ghi đè, tuy nhiên biết đối tượng không bao giờ nên được sử dụng như là một chìa khóa. Nếu không có một phương thức hữu ích bằng các đối tượng, các tài sản trên các bộ sưu tập trong nUnit không hoạt động. –

+0

Đó sẽ là một sự lạm dụng rõ ràng của Object.Equals(). Trên thực tế, tôi muốn phương thức này được đặt tên là Equivalent(), chứ không phải là Equals(), vì nó là khái niệm tương đương, chứ không phải tên, được áp dụng rộng rãi, và trong một số trường hợp, nó có thể hữu ích cho một số đối tượng một phương thức Equals() với ngữ nghĩa lỏng lẻo hơn. Ví dụ, nếu tôi có druthers của tôi, Equivalent (1.00m, 1.0m) sẽ là false, nhưng Equals (1.00m, 1.0m) sẽ là đúng. Bằng sẽ được xác định bởi spec như một tài sản tạm thời, không giống như Equivalent mà sẽ được (bất cứ khi nào được thực hiện đúng) bất biến. – supercat

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