Hãy để tôi không đồng ý. Việc triển khai @ LukeH không phải là Chung.
tôi sẽ giải thích lý do tại sao nó không phải là Generic:
Comparer<T>.Default
liên quan đến việc kiểm tra T lúc chạy-thời gian để xác định xem nó thực hiện IComparable<T>
, IComparable
hay không. Mặc dù hành vi này không được ghi lại đầy đủ trong http://msdn.microsoft.com/en-us/library/azhsac5f.aspx, chúng tôi có thể khấu trừ vì Comparer<T>.Default
ném ngoại lệ khi T không thực hiện cả hai. Nếu việc kiểm tra được thực hiện tại thời gian biên dịch sẽ không cần một ngoại lệ (thời gian chạy), với một lỗi biên dịch thời gian là đủ.
Sau đó, như Comparer<T>.Default
sử dụng Phản ánh, điều này có nghĩa là chi phí cao trên Thời gian chạy, sau đó ...., KHÔNG PHẢI là chung ... Tại sao?
Vì Lập trình chung có nghĩa là: Một thuật toán đơn (Chung) có thể bao gồm nhiều hiệu quả cho các phiên bản viết tay.
Lấy ví dụ. Phiên bản viết tay cho số nguyên sẽ là:
public static int Max(int x, int y)
{
return (x.CompareTo(y) > 0) ? x : y;
}
Rất đơn giản, chỉ liên quan đến so sánh (hoặc có thể nhiều hơn, tùy thuộc vào cách Int32.CompareTo() được triển khai). Nếu chúng ta sử dụng cách thực hiện của @ LukeH, chúng ta sẽ thêm Sự phản chiếu vào một cái gì đó rất đơn giản.
Nói tóm lại:
- Luôn thích lỗi biên dịch thời gian để chạy thời gian Exceptions (đây không phải là Javascript, Ruby, ... :-))
- thực hiện này là kém hiệu quả so với phiên bản viết tay (đối với mọi loại)
Mặt khác. Bạn nghĩ Max nên trả lại khi x và y là tương đương?
tôi bắt đầu phân tích việc triển khai thực Generic ....
Việc thực hiện lý tưởng sẽ là một cái gì đó giống như ...
public static T Max<T>(T x, T y, Func<T, T, int> cmp)
{
return (cmp(x, y) > 0) ? x : y;
}
//Pseudo-code (note the 'or' next to 'where')
public static T Max<T>(T x, T y) where T: IComparable<T> or IComparable
{
return Max(x, y, (a, b) => { return a.CompareTo(b); });
}
này là không thể trong C#, lần thử tiếp theo có thể là ...
//pseudo-code
public static T Max<T>(T x, T y, Func<T, T, int> cmp)
{
return (cmp(x, y) > 0) ? x : y;
}
public static T Max<T>(T x, T y) where T: IComparable<T>
{
return Max(x, y, (a, b) => { return a.CompareTo(b); });
}
public static T Max<T>(T x, T y) where T: IComparable
{
return Max(x, y, (a, b) => { return a.CompareTo(b); });
}
Nhưng, điều này là không thể, vì độ phân giải quá tải không tính đến Generational Constraints ....
Sau đó, tôi sẽ bỏ qua IComparable
một cách có ý thức. Tôi sẽ lo lắng về việc IComparable<T>
public static T Max<T>(T x, T y, Func<T, T, int> cmp)
{
return (cmp(x, y) > 0) ? x : y;
}
public static T Max<T>(T x, T y) where T: IComparable<T>
{
return Max(x, y, (a, b) => { return a.CompareTo(b); });
}
ps. Tại sao giới hạn Max cho struct? Nó có thể hữu ích như nhau đối với các lớp, ví dụ như. dây. – Will
Nói chung cho bất cứ điều gì mà thực hiện 'IComparable'. – Joey
Bạn nói đúng, tôi không biết về giao diện IComparable. TY. – Feryt