Warisan Komentar untuk C # (sebenarnya bahasa apa pun)

95

Misalkan saya memiliki antarmuka ini

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

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

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

Dan kelas ini

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

Adakah cara, atau adakah alat yang memungkinkan saya secara otomatis memasukkan komentar dari setiap anggota di kelas atau antarmuka dasar?

Karena saya benci menulis ulang komentar yang sama untuk setiap sub-kelas turunan!

jumpinjackie
sumber
14
Saya tidak hanya membencinya tetapi juga sulit untuk membuatnya tetap sinkron.
Olivier Jacot-Descombes

Jawaban:

17

GhostDoc melakukan hal itu. Untuk metode yang tidak diwariskan, mencoba membuat deskripsi dari namanya.

FlingThing() menjadi "Flings the Thing"

James Curran
sumber
2
GhostDoc luar biasa, salah satu hal yang saya tidak tahu saya butuhkan tetapi sekarang tidak dapat dilakukan tanpa: o)
NikolaiDante
184
Dokumen yang dibuat secara otomatis sepertinya ide yang sangat buruk bagi saya. Mereka tidak menambahkan informasi yang berguna tetapi hanya meledakkan kode yang tidak perlu. Jika sebuah alat dapat memahami apa yang dilakukan metode dari namanya, maka seseorang juga dapat memahami dan tidak diperlukan dokumen.
Lensflare
8
@Lensflare Ini sangat benar. Saya pernah menggunakan kerangka kerja yang hanya memiliki komentar yang dihasilkan seperti itu, yang menambahkan informasi NO ke metode / kelas. Alih-alih "Metode ini melakukan ini dan itu", komentar seperti "Ini adalah metode XY kelas Z". xD Anda juga tidak dapat menelusuri kode, jadi masuk ke trial & error. Tidak akan lagi! :-)
itmuckel
15
@Lensflare Sementara saya 100% setuju dengan Anda sejauh mengandalkan AGDS seperti , saya harus menunjukkan bahwa AGDS tidak dimaksudkan untuk digunakan sebagai "melakukan itu semua" tombol ajaib seperti itu. Sebaliknya, mereka dimaksudkan untuk digunakan sebagai generator template untuk mengurangi jumlah boilerplate, dokumentasi berulang yang harus Anda tulis sendiri, sehingga Anda dapat fokus pada hal-hal penting. --- Sebagai contoh, dapat menghasilkan <summary>, <param>, <returns>, <throws>, etc...bagian untuk Anda. Berkali-kali dengan hasil yang cukup baik; di lain waktu membutuhkan koreksi atau perluasan, tetapi tetap mengurangi upaya secara keseluruhan.
XenoRo
5
Orang-orang dokumentasi bukan untuk pengembang itu untuk arsitek jadi pantat mereka semua tertutup: "Hei, bisakah kita membaca dokumentasi kode proyek Anda? Tentu, ini dia."
Trident D'Gao
157

Anda selalu dapat menggunakan <inheritdoc />tag:

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

Dengan menggunakan crefatribut tersebut, Anda bahkan dapat merujuk ke anggota yang sama sekali berbeda di kelas atau namespace yang sama sekali berbeda!

public class Foo
{
    /// <inheritdoc cref="System.String.IndexOf" />
    public void Bar() { ... } // this method will now have the documentation of System.String.IndexOf
}
Vadim
sumber
8
Saya bahkan tidak tahu <inheritdoc /> ada ... Tapi sejauh yang saya lihat, komentar untuk metode ini tidak muncul dengan Intellisense.
gerleim
12
@gerleim Lihat jawaban Jeff Heaton setahun sebelumnya, dan komentar di bawahnya. Sandcastle memiliki <inheritdoc />, bukan C #.
rbwhitaker
4
Saya melihat komentar dari antarmuka di intellisense dengan inheritdoc, dan juga jika tidak ada kode-doc sama sekali pada kelas turunan. Tapi itu bisa jadi karena saya punya resharper.
Tim Abell
9
Resharper 2017.2 telah meningkatkan dukungan untuk inheritdoc jetbrains.com/resharper/whatsnew
Dav Evans
4
Visual Studio Enterprise 2017 (versi 15.9.3) tidak menunjukkan komentar yang diwariskan untuk saya.
herzbube
26

Gunakan /// <inheritdoc/>jika Anda menginginkan warisan. Hindari GhostDoc atau semacamnya.

Saya setuju bahwa komentar tidak diwariskan adalah hal yang menjengkelkan. Ini akan menjadi tambahan yang cukup sederhana untuk dibuat jika seseorang punya waktu (saya harap saya melakukannya).

Karena itu, dalam basis kode kami, kami meletakkan komentar XML pada antarmuka saja dan menambahkan komentar implementasi tambahan ke kelas. Ini berfungsi untuk kami karena kelas kami bersifat pribadi / internal dan hanya antarmuka yang publik. Setiap kali kita menggunakan objek melalui antarmuka kita memiliki tampilan komentar penuh dalam kecerdasan.

GhostDoc adalah permulaan yang baik dan telah mempermudah proses menulis komentar. Ini sangat berguna untuk menjaga komentar tetap up-to-date ketika Anda menambah / menghapus parameter, menjalankan ulang GhostDoc dan itu akan memperbarui deskripsi.

Dennis
sumber
Saya bingung - Anda mengatakan hindari GhostDoc, tetapi pada akhirnya Anda tampaknya mendukung GhostDoc untuk membantu mempermudah. Bisakah Anda menjelaskan apa yang Anda maksud?
Mike Marynowski
Terima kasih @MikeMarynowski. Ini nasihat lama . Saya rasa saya ingin mengatakan pada saat itu bahwa GhostDoc, seperti generator lainnya, akan menambahkan komentar tetapi dengan detail yang hampir tidak berguna misalnya <param name="origin">The origin.</param>. Lihat ghostdoc mengatakan hal - hal terkutuk untuk lebih banyak contoh. Visual Studio sekarang memiliki linting dan generator yang jauh lebih baik untuk xmldocs untuk memberi tahu Anda ketika parameter + dokumen tidak selaras sehingga GhostDoc (atau alat lain) tidak diperlukan lagi.
Dennis
15

Java memiliki ini, dan saya menggunakannya sepanjang waktu. Lakukan saja:

/**
 * {@inheritDoc}
 */

Dan alat Javadoc mengetahuinya.

C # memiliki penanda yang mirip:

<inheritDoc/>

Anda dapat membaca lebih lanjut di sini:

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

JeffHeaton
sumber
37
C # tidak memiliki <inheritdoc/>penanda: Sandcastle memilikinya. shfb.codeplex.com
Eric Dand
8
Ada permintaan fitur suara pengguna untuk menambahkan <inheritdoc /> ke C #. Naik-vote di visualstudio.uservoice.com/forums/121579-visual-studio/…
deadlydog
1
Baik C # maupun Java (atau bahasa pemrograman lainnya) tidak memiliki elemen "XML doc". Ini adalah komentar . Para penyusun tidak tahu apa-apa tentang mereka. Semuanya ketat digunakan oleh pembuat dokumentasi pihak ketiga, apakah itu javadoc atau sandcastle atau apa pun.
James Curran
4
Ketika Java atau C # dinyatakan, itu BIASANYA berarti komunitas alat terkait. Baik Java maupun C # tidak memiliki banyak kemampuan dalam arti literal. Ini akan menjadi argumen akademis untuk menyatakan bahwa Java atau C # tidak memiliki kemampuan untuk terhubung ke database, karena perpustakaan run time melakukan itu.
JeffHeaton
2
Visual Studio versi 16.4.0 dan yang lebih baru menyediakan intellisense untuk <inheritDoc />! docs.microsoft.com/en-us/visualstudio/releases/2019/…
ashbygeek
11

Saya akan mengatakan untuk langsung menggunakan

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

Dan

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

Anda harus meletakkan komentar ini tepat di baris sebelumnya dari kelas / metode Anda

Ini akan mendapatkan info dari komentar Anda misalnya dari antarmuka yang telah Anda dokumentasikan seperti:

    /// <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);
gatsby
sumber
Terima kasih atas sarannya! Pendekatan ini lebih eksplisit dan memecahkan masalah deskripsi kelas warisan dari kelas objek (bahkan saat mengimplementasikan antarmuka).
Denis Babarykin
8

Resharper memiliki opsi untuk menyalin komentar dari kelas atau antarmuka dasar.

svick.dll
sumber
1
Oh? Bagaimana? Saya menggunakan ReSharper dan saya tidak pernah melihat opsi itu saat mengimplementasikan atau mewarisi antarmuka ... Di mana dan bagaimana Anda menggunakan opsi itu?
Jazimov
2
@Jazimov Saat Anda Alt + Enter metode override, ada opsi untuk "Salin dokumentasi dari basis".
svick
8

Cara lain adalah dengan menggunakan <see />tag dokumentasi XML. Ini adalah upaya ekstra tetapi berhasil di luar kotak ...

Berikut beberapa contohnya:

/// <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() { ... }
}

Memperbarui:

Saya sekarang lebih suka menggunakan /// <inheritdoc/>yang sekarang didukung oleh ReSharper.

Mathias Rotter
sumber
1

Saya akhirnya membuat alat untuk pasca-proses file dokumentasi XML untuk menambahkan dukungan untuk mengganti <inheritdoc/>tag di file dokumentasi XML itu sendiri. Tersedia di www.inheritdoc.io (tersedia versi gratis).

K Johnson
sumber
0

Ada semacam solusi asli, yang saya temukan untuk .NET Core 2.2

Idenya adalah menggunakan <include>tag.

Anda dapat menambahkan <GenerateDocumentationFile>true</GenerateDocumentationFile>Anda .csprojfile.

Anda mungkin memiliki antarmuka:

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

Dan sesuatu yang diwarisi darinya:

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.");
    }
}

Oke, ini agak menakutkan, tetapi menambahkan elemen yang diharapkan ke file YourNamespace.xml.

Jika Anda membangun Debugkonfigurasi, Anda dapat menukar Releaseuntuk Debugdi fileatributinclude tag.

Untuk menemukan yang benar memberIni nameuntuk referensi hanya membuka dihasilkanDocumentation.xml berkas.

Saya juga berasumsi bahwa pendekatan ini memerlukan proyek atau solusi untuk dibangun setidaknya dua kali (pertama kali membuat file XML awal, dan kedua kalinya menyalin elemen darinya ke dirinya sendiri).

Sisi baiknya adalah Visual Studio memvalidasi elemen yang disalin, sehingga jauh lebih mudah untuk menjaga dokumentasi dan kode sinkron dengan antarmuka / kelas dasar, dll (misalnya nama argumen, nama parameter tipe, dll).

Di proyek saya, saya telah berakhir dengan <inheritdoc/>(untuk DocFX) dan <include/>(Untuk menerbitkan paket NuGet dan untuk validasi di 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();
Konard
sumber