Nhận xét Kế thừa cho C # (thực tế là bất kỳ ngôn ngữ nào)


93

Giả sử tôi có giao diện này

public interface IFoo
{
    ///<summary>
    /// Foo method
    ///</summary>
    void Foo();

    ///<summary>
    /// Bar method
    ///</summary>
    void Bar();

    ///<summary>
    /// Situation normal
    ///</summary>
    void Snafu();
}

Và lớp học này

public class Foo : IFoo
{
    public void Foo() { ... }
    public void Bar() { ... }
    public void Snafu() { ... }
}

Có cách nào hoặc có công cụ nào có thể cho phép tôi tự động đưa vào nhận xét của từng thành viên trong lớp cơ sở hoặc giao diện không?

Bởi vì tôi ghét viết lại các nhận xét giống nhau cho mỗi lớp con dẫn xuất!


14
Tôi không chỉ ghét nó mà còn rất khó để giữ chúng đồng bộ.
Olivier Jacot-Descombes

Câu trả lời:


17

GhostDoc thực hiện chính xác điều đó. Đối với các phương thức không được kế thừa, nó cố gắng tạo mô tả ngoài tên.

FlingThing() trở thành "Flings the Thing"


2
GhostDoc là tuyệt vời, một trong những điều mà tôi không biết là tôi cần nhưng bây giờ không thể làm mà không có: o)
NikolaiDante

180
Đối với tôi, các tài liệu được tạo tự động dường như là một ý tưởng rất tồi. Họ không thêm bất kỳ thông tin hữu ích nào mà chỉ làm hỏng mã một cách không cần thiết. Nếu một công cụ có thể hiểu những gì một phương thức thực hiện từ tên của nó, thì một người cũng có thể hiểu và không cần tài liệu.
Lensflare

8
@Lensflare Điều này rất đúng. Tôi đã từng phải sử dụng một khung công tác chỉ có các nhận xét được tạo ra như vậy, KHÔNG thêm thông tin vào phương thức / lớp. Thay vì "Phương thức này thực hiện điều này và điều đó", các nhận xét như "Đây là phương thức XY của lớp Z". xD Ngoài ra, bạn không duyệt qua mã, vì vậy nó đã chuyển sang giai đoạn thử nghiệm và lỗi. Không bao giờ lặp lại! :-)
itmuckel

15
@Lensflare Trong khi tôi 100% đồng ý với bạn như xa như dựa vào AGDs như là , tôi phải chỉ ra rằng AGDs không có nghĩa là để được sử dụng như "làm tất cả" nút diệu như thế. Thay vào đó, chúng được dùng làm trình tạo mẫu để giảm số lượng tài liệu lặp đi lặp lại mà bạn phải tự viết, vì vậy bạn có thể tập trung vào những thứ quan trọng. --- Ví dụ, nó có thể tạo ra <summary>, <param>, <returns>, <throws>, etc...phần dành cho bạn. Nhiều lần với kết quả tốt-đủ; thời gian khác cần sửa chữa hoặc mở rộng, nhưng vẫn giảm nỗ lực chung.
XenoRo

5
mọi người, tài liệu không dành cho nhà phát triển mà là tài liệu dành cho kiến ​​trúc sư nên tất cả đều được che đậy: "Này, chúng tôi có thể đọc tài liệu mã của dự án của bạn không? Chắc chắn rồi, đây rồi."
Trident D'Gao

151

Bạn luôn có thể sử dụng <inheritdoc />thẻ.

public class Foo : IFoo
{
    /// <inheritdoc />
    public void Foo() { ... }
    /// <inheritdoc />
    public void Bar() { ... }
    /// <inheritdoc />
    public void Snafu() { ... }
}

7
Tôi không biết <inheritdoc /> thậm chí còn tồn tại ... Nhưng theo như tôi có thể thấy, nhận xét cho phương thức này không hiển thị với intellisense.
gerleim

12
@gerleim Hãy xem câu trả lời của Jeff Heaton từ một năm trước và nhận xét bên dưới nó. Lâu đài cát có <inheritdoc />, không phải C #.
rbwhitaker

4
Tôi thấy các nhận xét từ giao diện trong intellisense với inheritdoc, và nếu không có mã-doc nào trên lớp dẫn xuất. Nhưng đó có thể là do tôi có bộ sạc lại.
Tim Abell

9
Resharper 2017.2 đã cải thiện hỗ trợ cho inheritdoc jetbrains.com/resharper/whatsnew
Dav Evans

3
Visual Studio Enterprise 2017 (phiên bản 15.9.3) không hiển thị nhận xét kế thừa cho tôi.
herzbube 20/1218

26

Sử dụng /// <inheritdoc/> nếu bạn muốn kế thừa. Tránh GhostDoc hoặc bất cứ thứ gì tương tự.

Tôi đồng ý rằng thật khó chịu khi nhận xét không được kế thừa. Nó sẽ là một bổ trợ khá đơn giản để tạo nếu ai đó có thời gian (tôi ước tôi đã làm như vậy).

Điều đó nói rằng, trong cơ sở mã của chúng tôi, chúng tôi chỉ đặt các nhận xét XML trên các giao diện và thêm các nhận xét triển khai bổ sung vào lớp. Điều này phù hợp với chúng tôi vì các lớp của chúng tôi là riêng tư / nội bộ và chỉ giao diện là công khai. Bất cứ khi nào chúng tôi sử dụng các đối tượng thông qua các giao diện, chúng tôi có đầy đủ các nhận xét hiển thị trong nội dung.

GhostDoc là một khởi đầu tốt và đã giúp quá trình viết nhận xét dễ dàng hơn. Điều đặc biệt hữu ích là giữ cho các nhận xét được cập nhật khi bạn thêm / xóa các tham số, chạy lại GhostDoc và nó sẽ cập nhật mô tả.


Tôi bối rối - bạn nói tránh GhostDoc, nhưng cuối cùng, bạn dường như đã xác nhận GhostDoc giúp mọi thứ dễ dàng hơn. Bạn có thể làm rõ những gì bạn muốn nói?
Mike Marynowski

Cảm ơn @MikeMarynowski. Đây là lời khuyên . Tôi nghĩ rằng tôi muốn nói vào thời điểm đó rằng GhostDoc, giống như bất kỳ trình tạo nào khác, sẽ thêm nhận xét nhưng với các chi tiết gần như vô dụng, ví dụ <param name="origin">The origin.</param>. Xem ghostdoc nói những điều đáng sợ nhất để biết thêm ví dụ. Visual Studio hiện có trình tạo và trình tạo linting tốt hơn nhiều cho xmldocs để cho bạn biết khi nào các thông số + tài liệu không căn chỉnh để GhostDoc (hoặc các công cụ khác) không còn cần thiết nữa.
Dennis

15

Java có cái này, và tôi sử dụng nó mọi lúc. Cứ làm đi:

/**
 * {@inheritDoc}
 */

Và công cụ Javadoc đã tìm ra điều đó.

C # có điểm đánh dấu tương tự:

<inheritDoc/>

Bạn có thể đọc thêm ở đây:

http://www.ewoodruff.us/shfbdocs/html/79897974-ffc9-4b84-91a5-e50c66a0221d.htm


37
C # không có <inheritdoc/>điểm đánh dấu: Lâu đài cát có nó. shfb.codeplex.com
Eric Dand

8
Có một yêu cầu tính năng giọng nói của người dùng để thêm <inheritdoc /> vào C #. Đi lên-phiếu nó ở visualstudio.uservoice.com/forums/121579-visual-studio/...
deadlydog

1
Cả C # và Java (hoặc bất kỳ ngôn ngữ lập trình nào khác) đều không có bất kỳ phần tử "tài liệu XML" nào. Đây là những bình luận . Các trình biên dịch không biết gì về chúng. Tất cả chúng đều được sử dụng nghiêm ngặt bởi trình tạo tài liệu của bên thứ ba, cho dù đó là javadoc hay lâu đài cát hay bất cứ thứ gì.
James Curran

4
Khi Java hoặc C # được nêu, nó THỰC SỰ có nghĩa là cộng đồng các công cụ liên quan. Cả Java và C # đều không có nhiều khả năng theo đúng nghĩa đen. Sẽ là một lập luận học thuật nếu nói rằng Java hoặc C # thiếu khả năng kết nối với cơ sở dữ liệu, bởi vì thư viện thời gian chạy thực hiện điều đó.
JeffHeaton

2
Visual Studio phiên bản 16.4.0 và mới hơn cung cấp intellisense cho <inheritDoc />! docs.microsoft.com/en-us/visualstudio/releases/2019/…
ashbygeek

10

Tôi muốn nói là sử dụng trực tiếp

/// <inheritdoc cref="YourClass.YourMethod"/>  --> For methods inheritance

/// <inheritdoc cref="YourClass"/>  --> For directly class inheritance

Bạn phải đặt nhận xét này ngay trên dòng trước của lớp / phương thức của bạn

Thao tác này sẽ lấy thông tin về nhận xét của bạn, ví dụ từ giao diện mà bạn đã ghi lại như:

    /// <summary>
    /// This method is awesome!
    /// </summary>
    /// <param name="awesomeParam">The awesome parameter of the month!.</param>
    /// <returns>A <see cref="AwesomeObject"/> that is also awesome...</returns>
    AwesomeObject CreateAwesome(WhateverObject awesomeParam);

Cảm ơn về lời khuyên! Cách tiếp cận này rõ ràng hơn và giải quyết vấn đề mô tả lớp kế thừa từ lớp đối tượng (ngay cả khi thực hiện giao diện).
Denis Babarykin

8

Resharper có một tùy chọn để sao chép các nhận xét từ lớp cơ sở hoặc giao diện.


1
Oh? Làm sao? Tôi sử dụng ReSharper và tôi chưa bao giờ thấy tùy chọn đó khi triển khai hoặc kế thừa một giao diện ... Nó ở đâu và bạn sử dụng tùy chọn đó như thế nào?
Jazimov

2
@Jazimov Khi bạn Alt + Enter phương thức ghi đè, có một tùy chọn để "Sao chép tài liệu từ cơ sở".
svick

8

Một cách khác là sử dụng <see />thẻ tài liệu XML. Đây là một số nỗ lực bổ sung nhưng hoạt động hiệu quả ...

Dưới đây là một số ví dụ:

/// <summary>
/// Implementation of <see cref="IFoo"/>.
/// </summary>
public class Foo : IFoo
{
    /// <summary>
    /// See <see cref="IFoo"/>.
    /// </summary>
    public void Foo() { ... }

    /// <summary>
    /// See <see cref="IFoo.Bar"/>
    /// </summary>
    public void Bar() { ... }

    /// <summary>
    /// This implementation of <see cref="IFoo.Snafu"/> uses the a caching algorithm for performance optimization.
    /// </summary>
    public void Snafu() { ... }
}

Cập nhật:

Bây giờ tôi thích sử dụng /// <inheritdoc/>mà hiện đã được hỗ trợ bởi ReSharper.


1

Tôi đã kết thúc việc tạo một công cụ để xử lý hậu các tệp tài liệu XML để thêm hỗ trợ cho việc thay thế <inheritdoc/>thẻ trong chính các tệp tài liệu XML. Có tại www.inheritdoc.io (có phiên bản miễn phí).


0

Vâng, có một loại giải pháp gốc, tôi đã tìm thấy cho .NET Core 2.2

Ý tưởng là sử dụng <include> thẻ.

Bạn có thể thêm <GenerateDocumentationFile>true</GenerateDocumentationFile>bạn.csproj một tập tin.

Bạn có thể có một giao diện:

namespace YourNamespace
{
    /// <summary>
    /// Represents interface for a type.
    /// </summary>
    public interface IType
    {
        /// <summary>
        /// Executes an action in read access mode.
        /// </summary>
        void ExecuteAction();
    }
}

Và một cái gì đó kế thừa từ nó:

using System;

namespace YourNamespace
{
    /// <summary>
    /// A type inherited from <see cref="IType"/> interface.
    /// </summary>
    public class InheritedType : IType
    {
        /// <include file='bin\Release\netstandard2.0\YourNamespace.xml' path='doc/members/member[@name="M:YourNamespace.IType.ExecuteAction()"]/*'/>
        public void ExecuteAction() => Console.WriteLine("Action is executed.");
    }
}

Ok, nó có một chút đáng sợ, nhưng nó thêm các yếu tố được mong đợi vào YourNamespace.xml.

Nếu bạn xây dựng Debugcấu hình, bạn có thể trao đổi Releasecho Debugtrong filethuộc tính của includethẻ.

Để tìm một đúng membernameđể tham khảo được tạo ra chỉ cần mở Documentation.xmltập tin.

Tôi cũng giả định rằng cách tiếp cận này yêu cầu một dự án hoặc giải pháp phải được xây dựng ít nhất hai lần (lần đầu tiên để tạo tệp XML ban đầu và lần thứ hai để sao chép các phần tử từ nó sang chính nó).

Mặt sáng sủa là Visual Studio xác thực các phần tử được sao chép, vì vậy việc giữ cho tài liệu và mã đồng bộ với giao diện / lớp cơ sở, v.v. sẽ dễ dàng hơn nhiều (ví dụ: tên của đối số, tên của tham số kiểu, v.v.).

Tại dự án của mình, tôi đã kết thúc với cả <inheritdoc/>(cho DocFX) và <include/>(Để xuất bản các gói NuGet và để xác thực tại Visual Studio):

        /// <inheritdoc />
        /// <include file='bin\Release\netstandard2.0\Platform.Threading.xml' path='doc/members/member[@name="M:Platform.Threading.Synchronization.ISynchronization.ExecuteReadOperation(System.Action)"]/*'/>
        public void ExecuteReadOperation(Action action) => action();
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.