C # chung chung “nơi ràng buộc” với định nghĩa “bất kỳ kiểu chung nào”?


113

Hãy để tôi ví dụ:

  1. Tôi có một số định nghĩa chung về lớp / giao diện:

    interface IGenericCar< T > {...}

  2. Tôi có một lớp / giao diện khác mà tôi muốn liên kết với lớp ở trên, ví dụ:

    interface IGarrage< TCar > : where TCar: IGenericCar< (**any type here**) > {...}

Về cơ bản, tôi muốn IGarrage chung của mình phụ thuộc vào IGenericCar, bất kể đó là IGenericCar<int>hay IGenericCar<System.Color>, bởi vì tôi không có bất kỳ sự phụ thuộc nào vào loại đó.

Câu trả lời:


142

Thông thường có 2 cách để đạt được điều này.

Option1 : Thêm một tham số khác để IGarrageđại diện cho tham số Tsẽ được chuyển vào IGenericCar<T>ràng buộc:

interface IGarrage<TCar,TOther> where TCar : IGenericCar<TOther> { ... }

Tùy chọn 2 : Xác định giao diện cơ sở IGenericCar<T>không chung chung và hạn chế đối với giao diện đó

interface IGenericCar { ... }
interface IGenericCar<T> : IGenericCar { ... }
interface IGarrage<TCar> where TCar : IGenericCar { ... }

6
Ok, nhưng tôi nên làm gì nếu tôi cần sử dụng loại chung của mình Tbên trong IGarage<TCar>? Tôi không thể thấy bất kỳ khả năng nào trong tùy chọn 2. Giải pháp tốt nhất sẽ là nếu IGarage<TCar>loại được tìm thấy Tbằng loại phân tích TCar.
pt12lol

2
Đối với hậu thế, một kiểu CÓ THỂ được tạo có tham số kiểu của kiểu chung thô, nhưng chỉ với phản xạ trong thời gian chạy và lớp đã tạo không bao giờ có thể được tạo, bởi vì tham số kiểu chung thô không bao giờ có thể được tạo tự động mà không có định nghĩa đầy đủ của tham số loại tương ứng ITS. Tôi không thấy điều này có thể hữu ích ở đâu, ngoại trừ trường hợp các thành viên tĩnh siêu chung chung của lớp ngoài cùng (tức là IGarage<IGenericCar<?>>.TellMeAboutCarsInGeneral(), có thể là kết quả của thiết kế kém), nhưng tôi đã thực hiện nó trong quá trình mày mò của mình, và nó có khả năng.
Michael Hoffmann

Tôi giả sử bất kỳ ai cũng có thể thêm giao diện IGenericCar vào một lớp và phá vỡ phương thức bị ràng buộc bằng một lớp không mong muốn.
Không ăn

2
@ pt12lol: Nếu IGarrage<TCar>thực sự xử lý kiểu chung cơ bản (ví dụ: nó xử lý một thuộc tính của kiểu đã nói), thì nó cần biết kiểu, điều này yêu cầu bạn chỉ định kiểu, đó là tùy chọn 1 (tùy chọn khả thi duy nhất sau đó). Tuy nhiên, nếu IGarrage<TCar>không xử lý trực tiếp kiểu chung cơ bản (tất cả IGarrage<TCar>mã là bất khả tri của kiểu cơ bản này), thì tùy chọn 2 là hợp lệ.
Flater

6

Sẽ có ý nghĩa gì nếu làm điều gì đó như:

interface IGenericCar< T > {...}
interface IGarrage< TCar, TCarType > 
    where TCar: IGenericCar< TCarType > {...}
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.