Tại sao sử dụng một phương thức chung với một ràng buộc kiểu thay vì chính kiểu đó?


14

Trong một câu hỏi StackExchange khác, tôi nhận thấy ai đó sử dụng nguyên mẫu này:

void DoSomething<T>(T arg) where T: SomeSpecificReferenceType
{
    //Code....
}

Hãy nhớ rằng chỉ có một ràng buộc kiểu duy nhất ( SomeSpecificReferenceType), sự khác biệt và lợi thế của việc viết nó như thế nào, thay vì chỉ đơn giản là:

void DoSomething(SomeSpecificReferenceType arg)
{
    //Code....
}

Trong cả hai trường hợp, argsẽ phải kiểm tra kiểu biên dịch thời gian. Trong cả hai trường hợp, phần thân của phương thức có thể dựa một cách an toàn vào kiến ​​thức argthuộc về (hoặc là hậu duệ) của một loại cụ thể được biết đến tại thời điểm biên dịch.

Đây có phải là một trường hợp của một nhà phát triển quá nhiệt tình tìm hiểu về thuốc generic trước khi tìm hiểu về thừa kế thông thường? Hoặc có một lý do chính đáng tại sao một chữ ký phương thức sẽ được viết theo cách này?


Tôi hầu như không biết C # vì vậy đây chỉ là dự đoán, nhưng điều này không cho phép gửi tĩnh hiệu quả hơn thay vì gửi động?
Anton Barkovsky

Câu trả lời:


13

Đây có phải là một trường hợp của một nhà phát triển quá nhiệt tình tìm hiểu về thuốc generic trước khi tìm hiểu về thừa kế thông thường?

Vâng, nó có thể là.

Hoặc có một lý do chính đáng tại sao một chữ ký phương thức sẽ được viết theo cách này?

Có lẽ . Nói chung, sẽ có ý nghĩa hơn nếu có một giá trị trả về có liên quan Thoặc tham số khác được sử dụng T.

Nhưng, có thể các phần bên trong của mã sử dụng T(có thể là một đối số cho trình tuần tự hóa?) Và cần sử dụng cụ thể Tchứ không phải lớp ràng buộc. Thỉnh thoảng bạn sẽ thấy rằng khi ràng buộc là một giao diện được ghép nối với newràng buộc và can đảm của phương thức tạo ra Ts vì một số lý do.

Vì vậy, trong khi hiếm khi thấy phiên bản ràng buộc cần thiết, có đôi khi nó là như vậy. Và nó luôn luôn có thể là phương pháp sử dụng cần đến nó, nhưng bây giờ không và các nhà phát triển để lại nó như là không giới thiệu một sự thay đổi phá vỡ.


1

Tôi nghĩ rằng tôi nhớ bản thân mình gõ một câu trả lời có chứa điều này.

Vào thời điểm đó, lý do là như thế này:
(Mã có thể khác. Chỉ để minh họa một trong những lý do có thể khiến tại sao có một ràng buộc về tham số loại trong một phương thức chung.)

class SomeSingleton
{
    static Dictionary<Type, List<object>> staticTypeSpecificList;
    public void AddObjectToList<T>(T t) where T : SomeCommonThing
    {
        Type tt = t.GetType();
        List<object> list;
        if (!staticTypeSpecificList.TryGet(tt, out list))
        {
            list = new List<object>();
            staticTypeSpecificList.Add(tt, list);
        }
        list.Add(t);
    }
}

Về cơ bản, mã được đưa vào các thao tác mã hóa thủ công. Nó cũng có thể được trộn lẫn với một số công cụ phản ánh.

Ví dụ, bằng cách sử dụng Method<T>(T arg) where T : ..., người ta có thể thay thế arg.GetType()bằng typeof(T). Mặc dù vậy, tôi không biết lựa chọn đó là tốt hay xấu.

Tôi đoán đây chỉ là một ví dụ của tác giả (có thể là tôi hoặc người khác) không suy nghĩ cẩn thận về tất cả các khả năng của mã hóa, đồng thời tập trung quá nhiều vào một câu hỏi / vấn đề khác.


"người ta có thể thay thế arg.GetType () bằng typeof (T)". Điều này hữu ích khi arg có thể là null, ví dụ trong một số trường hợp tuần tự hóa.
walpen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.