Kế thừa từ một lớp cơ sở chung, áp dụng một ràng buộc và triển khai một giao diện trong C #


117

Đây là một câu hỏi cú pháp. Tôi có một lớp chung đang kế thừa từ một lớp cơ sở chung và đang áp dụng một ràng buộc cho một trong các tham số kiểu. Tôi cũng muốn lớp dẫn xuất triển khai một giao diện. Đối với cuộc đời của tôi, tôi dường như không thể tìm ra cú pháp chính xác.

Đây là những gì tôi có:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

Điều đầu tiên nghĩ đến là:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Nhưng điều đó không chính xác vì điều đó khiến T2 cần triển khai cả IBar và IFoo, không phải DerivedFoo để triển khai IFoo.

Tôi đã thử một chút Google Googling, sử dụng dấu hai chấm, dấu chấm phẩy, v.v. nhưng tôi không thành công. Tôi chắc rằng câu trả lời rất đơn giản.


Tôi không thể hiểu câu trả lời của @ Adam khi tôi xem một lần nhưng sau 2 phút, tôi có thể hiểu nó là gì, cảm ơn bạn đã trả lời. Lớp phát sinh có nhiều hơn một triển khai có thể là điểm này. Dù sao tôi muốn hiển thị ký hiệu của nó cho những người khác. "class DerivedClass <Type>: ParentClass trong đó Type: IType". Không nên có gì giữa lớp được triển khai cuối cùng và mệnh đề where.
nurisezgin

Câu trả lời:


173

Bạn bao gồm toàn bộ chữ ký của lớp trước khi bạn xác định các ràng buộc chung.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}

5
Đối với những người khác, tôi đã nội bộ hóa điều này là, một lớp chỉ nhận được một mệnh đề where và nó đi ở cuối cho bất kỳ & tất cả các ràng buộc kiểu chung.
Andy V

@Visser Nó được phép có nhiều nơi khoản, class Test <T1, T2> nơi T1: Interface1 nơi T2: Interface2
bwing

@Visser vâng, những gì bwing đã nói, mỗi mệnh đề where có thể có nhiều ràng buộc… vì vậy cú pháp từ bài đăng ban đầu là đúng, nó chỉ có nghĩa là một cái gì đó khác mà op muốn. where T2 : IBar, IFoo chỉ có nghĩa là T2phải thực hiện cả hai giao diện thay vì DerivedFoo<T1,T2> thực hiệnIFoo
v01pe

18

Khuyến nghị của tôi: khi bạn có câu hỏi về cú pháp của ngôn ngữ C #, hãy đọc thông số kỹ thuật; đó là lý do tại sao chúng tôi xuất bản nó. Bạn sẽ muốn đọc phần 10.1.

Để trả lời câu hỏi cụ thể của bạn, thứ tự của các thứ trong khai báo lớp là:

  • thuộc tính, trong dấu ngoặc vuông
  • bổ ngữ ("công khai", "tĩnh", v.v.)
  • "một phần"
  • "lớp học"
  • tên lớp
  • danh sách khai báo tham số kiểu được phân tách bằng dấu phẩy bên trong dấu ngoặc nhọn
  • dấu hai chấm theo sau danh sách các kiểu cơ sở được phân tách bằng dấu phẩy (lớp cơ sở và các giao diện được triển khai, lớp cơ sở phải đi trước nếu có)
  • loại ràng buộc tham số
  • phần thân của lớp, được bao quanh bởi các nẹp
  • dấu chấm phẩy

Mọi thứ trong danh sách đó là tùy chọn ngoại trừ "lớp", tên và nội dung, nhưng mọi thứ phải xuất hiện theo thứ tự đó nếu nó xuất hiện.


95
Eric, trong khi tôi vô cùng tôn trọng bạn với tư cách là một người chuyên nghiệp và đánh giá cao phản hồi của bạn, tôi không thể không thất vọng bởi những gì xảy ra như một câu trả lời mài mòn. Bạn đang chỉ trích tôi vì đã chọn đặt câu hỏi trên một trang Hỏi & Đáp về lập trình về việc định vị, tải xuống và tìm kiếm thông qua tài liệu Word 503 trang kỹ thuật cao bị chôn vùi trong một liên kết trong MSDN. Đó là khá thô. Đây là cách sử dụng thời gian hiệu quả nhất của tôi và có thêm lợi ích là nó có thể giúp ích cho người khác sau này. Liên kết đến C # Lang Spec cho những người quan tâm là: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby

17
Không có ý định chỉ trích. Có một sự thiên vị phổ biến trong giao tiếp thuần văn bản khiến những tuyên bố đơn giản về sự kiện nghe có vẻ thô thiển và phiến diện; Tôi cố gắng đọc một cách trôi chảy khi được cung cấp danh sách các sự kiện hữu ích và khuyên bạn nên làm như vậy. Tôi đứng về phía đề nghị của tôi; nếu bạn có câu hỏi về cú pháp, thông số kỹ thuật sẽ trả lời chúng một cách dứt khoát và bắt đầu bằng một mục lục hữu ích để xác định định nghĩa của các cú pháp cụ thể.
Eric Lippert

3
Dan, tìm thông số C # đơn giản như nhập 'C # Spec' vào Google và nhấn nút 'Tôi may mắn'. Và nếu bạn là nhà phát triển C # chuyên nghiệp, bạn nên có thông số C # ở định dạng PDF trên máy của mình. Ngoài ra, tôi cũng không có ý chỉ trích bạn. Tôi không quen đọc spec trước đó nhưng tôi đã bắt đầu đọc nó nhờ Jon, Eric và Pavel, những người luôn trích dẫn C # spec cho bất kỳ câu hỏi nào. Tôi nhận thấy rằng thông số C #, mặc dù đôi khi có thể khó đọc, nhưng là một cách tuyệt vời để học về ngôn ngữ này.
SolutionYogi

@Eric Lippert: Đủ công bằng. Cảm ơn bạn đã trả lời của bạn. Như một gợi ý mang tính xây dựng, sẽ rất hữu ích nếu Microsoft tích hợp trực tiếp nội dung của thông số kỹ thuật vào MSDN ngoài việc nó tồn tại dưới dạng một bản tải xuống riêng biệt. Phiên bản Visual Studio .Net MSDN có phiên bản tích hợp của thông số kỹ thuật, nhưng không có phiên bản mới hơn. Tôi đã nghĩ đến việc mua sách của Anders Hejlberg, nhưng với .Net 4.0 sắp ra mắt, tôi vẫn chưa muốn làm. amazon.com/C-Programming-Language-3rd/dp/0321562992 Cảm ơn.
Dan Rigby

2
C ++ yêu cầu khai báo lớp phải kết thúc bằng dấu chấm phẩy. Nhiều nhà phát triển C # đến từ nền tảng C ++; đôi khi ngón tay của họ đưa dấu chấm phẩy vào mà não của họ không tham gia. :-) Có một số cấu trúc trong C # có một nửa tùy chọn trong đó C ++ yêu cầu một cấu trúc. Nó khá nhiều chỉ là một sự tiện lợi nhỏ. Tôi cho rằng nó cũng cho phép bạn gọi ra một cách tinh vi khi khai báo kiểu kết thúc so với khai báo thân phương thức.
Eric Lippert

8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }

2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Đây là một phần mở rộng ra khỏi các câu trả lời hiện có. Nó được mặc định là stringnếu bạn không cung cấp một loại. Tôi đã không triển khai một giao diện nhưng điều đó sẽ không yêu cầu bất kỳ điều gì khác với bình thường.

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.