Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide, var olan nesne odaklı bir örneği (önceki öğreticiden) alır ve XML belge açıklamaları ile geliştirirsiniz. XML belgeleri açıklamaları yararlı IntelliSense araç ipuçları sağlar ve oluşturulan API başvuru belgelerine katılabilir. Hangi öğelerin açıklamaları hakettiğini, , , <summary>, <param>, <returns>, <value>, <remarks><example><seealso>ve <exception>gibi <inheritdoc>temel etiketlerin nasıl kullanılacağını ve tutarlı, amaca yönelik yorum oluşturmanın, kirlilik eklemeden sürdürülebilirliği, bulunabilirliği ve işbirliğini nasıl iyileştirdiğini öğrenirsiniz. Sonunda, örneğin genel yüzeyine açıklama eklediniz, projeyi XML belge dosyasını yayacak şekilde oluşturmuş ve bu açıklamaların doğrudan geliştirici deneyimine ve aşağı akış belgeleri araçlarına nasıl aktığını gördünüz.
Bu eğitimde, siz:
- C# projenizde XML belgeleri çıkışını etkinleştirin.
- XML dokümantasyon yorumlarını tiplere ve üyelere ekleyin ve yapılandırın.
- Projeyi derleyin ve oluşturulan XML belge dosyasını inceleyin.
Önkoşullar
XML belgelerini etkinleştirme
Önceki nesne odaklı öğreticide oluşturduğunuz projeyi yükleyin. Yeni bir başlangıç yapmak isterseniz, örneği klasörün altındaki dotnet/docs depodan snippets/object-oriented-programming kopyalayın.
Ardından, derleyicinin derlemenizle birlikte bir .xml dosya yayması için XML belge çıkışını etkinleştirin. Proje dosyasını düzenleyin ve bir <PropertyGroup> öğenin içine aşağıdaki özelliği ekleyin (veya onaylayın):
<GenerateDocumentationFile>True</GenerateDocumentationFile>
Visual Studio kullanıyorsanız, "build" özellik sayfasını kullanarak bunu etkinleştirebilirsiniz.
Projeyi oluşturun. Derleyici, genel olarak görünen türlerden ve üyelerden tüm /// açıklamaları toplayan bir XML dosyası oluşturur. Bu dosya IntelliSense araç ipuçlarını, statik analiz araçlarını ve aşağı akış belge oluşturma sistemlerini besler.
Projeyi şimdi oluşturun. Açıklamaları eksik <summary> olan tüm genel üyeler için uyarılar görürsünüz. Bu uyarıları, eksiksiz, kasıtlı belgeler sağlamanıza yardımcı olan bir to-do listesi olarak değerlendirin. Oluşturulan XML dosyasını açın (derleme çıkışınızın yanındadır) ve ilk yapıyı inceleyin. İlk başta, <members> henüz açıklama eklemediğiniz için bölüm boş olur:
<?xml version="1.0"?>
<doc>
<assembly>
<name>oo-programming</name>
</assembly>
<members>
</members>
</doc>
Dosya mevcutken hedeflenen XML açıklamalarını eklemeye başlayın ve her birinin oluşturulan çıktıda nasıl göründüğünü hemen doğrulayın. Kayıt türüyle Transaction başlayın:
namespace OOProgramming;
/// <summary>
/// Represents an immutable financial transaction with an amount, date, and descriptive notes.
/// </summary>
/// <param name="Amount">The transaction amount. Positive values represent credits/deposits, negative values represent debits/withdrawals.</param>
/// <param name="Date">The date and time when the transaction occurred.</param>
/// <param name="Notes">Descriptive notes or memo text associated with the transaction.</param>
public record Transaction(decimal Amount, DateTime Date, string Notes);
Belge açıklamaları ekleme
Şimdi türe kısa ve kullanışlı belgeler BankAccount eklemek için derleme uyarıları arasında geçiş yaparsınız. Her uyarı, <summary> (veya başka bir gerekli) öğesi bulunmayan bir genel erişim üyeyi gösterir. Uyarı listesini denetim listesi olarak değerlendirin. Kirlilik eklemekten kaçının: amaç, sabit değerler ve önemli kullanım kısıtlamalarını açıklamaya odaklanın; belirgin tür adlarını veya parametre türlerini yeniden düzenlemeyi atlayın.
- Projeyi yeniden oluşturun. Visual Studio veya Visual Studio Code'da Hata Listesi / Sorunlar panelini açın ve belge uyarıları için filtreleyin (CS1591). Komut satırında bir derleme çalıştırın ve konsola yayılan uyarıları gözden geçirin.
- İlk uyarıya (
BankAccountsınıfına) gidin. Bildirimin üzerindeki satıra yazın///. Düzenleyici bir<summary>öğenin taslağını oluşturur. Yer tutucuyu eylem odaklı tek bir cümleyle değiştirin. Cümle, hesabın etki alanındaki rolünü açıklar. Örneğin, işlemleri izler ve minimum bakiyeyi uygular. - Yalnızca davranışı açıklamanız gerekiyorsa ekleyin
<remarks>. Örnek olarak minimum bakiye zorlamanın nasıl çalıştığı veya hesap numaralarının nasıl oluşturulduğu verilebilir. Açıklamaları kısa tutun. - Her özellik (
Number,Owner,Balance) için, değerin neyi temsil ettiğini açıklayan bir///yazın ve önemsiz bir alıcı tarafından değerin nasıl döndürüldüğü değil, neyi ifade ettiği üzerine bir<summary>yazın. Bir özellik bir değer (gibiBalance) hesaplarsa, hesaplamayı doğrulayan bir<value>öğe ekleyin. - Her oluşturucu için, yalnızca parametre adını tekrarlamak yerine, her bağımsız değişkenin anlamını açıklayan
<summary>ve<param>öğelerini ekleyin. Bir aşırı yükleme başka bir öğeye temsilci atarsa, kısa bir<remarks>öğesi ekleyin. - Özel durum oluşturabilen yöntemler için, her kasıtlı özel durum türü için
<exception>etiketlerini ekleyin. Bunu tetikleyen koşulu açıklayın. Bağımsız değişken doğrulama yardımcıları tarafından atılan exceptions'ı, genel sözleşmenin bir parçası olmadığı sürece belgelemeyin. - Değer döndüren yöntemler için çağıranların aldığı şeyin kısa bir açıklamasını ekleyin
<returns>. Yöntem adını veya yönetilen türü yinelemekten kaçının. - Önce temel sınıfla
BankAccountçalışın.
Sürümünüz aşağıdaki koda benzer olmalıdır:
namespace OOProgramming;
/// <summary>
/// Represents a bank account with basic banking operations including deposits, withdrawals, and transaction history.
/// Supports minimum balance constraints and provides extensible month-end processing capabilities.
/// </summary>
public class BankAccount
{
/// <summary>
/// Gets the unique account number for this bank account.
/// </summary>
/// <value>A string representation of the account number, generated sequentially.</value>
public string Number { get; }
/// <summary>
/// Gets or sets the name of the account owner.
/// </summary>
/// <value>The full name of the person who owns this account.</value>
public string Owner { get; set; }
/// <summary>
/// Gets the current balance of the account by calculating the sum of all transactions.
/// </summary>
/// <value>The current account balance as a decimal value.</value>
public decimal Balance => _allTransactions.Sum(i => i.Amount);
private static int s_accountNumberSeed = 1234567890;
private readonly decimal _minimumBalance;
/// <summary>
/// Initializes a new instance of the BankAccount class with the specified owner name and initial balance.
/// Uses a default minimum balance of 0.
/// </summary>
/// <param name="name">The name of the account owner.</param>
/// <param name="initialBalance">The initial deposit amount for the account.</param>
/// <remarks>
/// This constructor is a convenience overload that calls the main constructor with a minimum balance of 0.
/// If the initial balance is greater than 0, it will be recorded as the first transaction with the note "Initial balance".
/// The account number is automatically generated using a static seed value that increments for each new account.
/// </remarks>
public BankAccount(string name, decimal initialBalance) : this(name, initialBalance, 0) { }
/// <summary>
/// Initializes a new instance of the BankAccount class with the specified owner name, initial balance, and minimum balance constraint.
/// </summary>
/// <param name="name">The name of the account owner.</param>
/// <param name="initialBalance">The initial deposit amount for the account.</param>
/// <param name="minimumBalance">The minimum balance that must be maintained in the account.</param>
/// <remarks>
/// This is the primary constructor that sets up all account properties. The account number is generated automatically
/// using a static seed value. If an initial balance is provided and is greater than 0, it will be added as the first
/// transaction. The minimum balance constraint will be enforced on all future withdrawal operations through the
/// <see cref="CheckWithdrawalLimit"/> method.
/// </remarks>
public BankAccount(string name, decimal initialBalance, decimal minimumBalance)
{
Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;
Owner = name;
_minimumBalance = minimumBalance;
if (initialBalance > 0)
MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
}
private readonly List<Transaction> _allTransactions = [];
/// <summary>
/// Makes a deposit to the account by adding a positive transaction.
/// </summary>
/// <param name="amount">The amount to deposit. Must be positive.</param>
/// <param name="date">The date when the deposit is made.</param>
/// <param name="note">A descriptive note about the deposit transaction.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the deposit amount is zero or negative.</exception>
/// <remarks>
/// This method creates a new <see cref="Transaction"/> object with the specified amount, date, and note,
/// then adds it to the internal transaction list. The transaction amount must be positive - negative amounts
/// are not allowed for deposits. The account balance is automatically updated through the Balance property
/// which calculates the sum of all transactions. There are no limits or restrictions on deposit amounts.
/// </remarks>
public void MakeDeposit(decimal amount, DateTime date, string note)
{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
}
var deposit = new Transaction(amount, date, note);
_allTransactions.Add(deposit);
}
/// <summary>
/// Makes a withdrawal from the account by adding a negative transaction.
/// Checks withdrawal limits and minimum balance constraints before processing.
/// </summary>
/// <param name="amount">The amount to withdraw. Must be positive.</param>
/// <param name="date">The date when the withdrawal is made.</param>
/// <param name="note">A descriptive note about the withdrawal transaction.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the withdrawal amount is zero or negative.</exception>
/// <exception cref="InvalidOperationException">Thrown when the withdrawal would cause the balance to fall below the minimum balance.</exception>
/// <remarks>
/// This method first validates that the withdrawal amount is positive, then checks if the withdrawal would
/// violate the minimum balance constraint by calling <see cref="CheckWithdrawalLimit"/>. The withdrawal is
/// recorded as a negative transaction amount. If the withdrawal limit check returns an overdraft transaction
/// (such as a fee), that transaction is also added to the account. The method enforces business rules through
/// the virtual CheckWithdrawalLimit method, allowing derived classes to implement different withdrawal policies.
/// </remarks>
public void MakeWithdrawal(decimal amount, DateTime date, string note)
{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
}
Transaction? overdraftTransaction = CheckWithdrawalLimit(Balance - amount < _minimumBalance);
Transaction? withdrawal = new(-amount, date, note);
_allTransactions.Add(withdrawal);
if (overdraftTransaction != null)
_allTransactions.Add(overdraftTransaction);
}
/// <summary>
/// Checks whether a withdrawal would violate the account's minimum balance constraint.
/// This method can be overridden in derived classes to implement different withdrawal limit policies.
/// </summary>
/// <param name="isOverdrawn">True if the withdrawal would cause the balance to fall below the minimum balance.</param>
/// <returns>A Transaction object representing any overdraft fees or penalties, or null if no additional charges apply.</returns>
/// <exception cref="InvalidOperationException">Thrown when the withdrawal would cause an overdraft and the account type doesn't allow it.</exception>
protected virtual Transaction? CheckWithdrawalLimit(bool isOverdrawn)
{
if (isOverdrawn)
{
throw new InvalidOperationException("Not sufficient funds for this withdrawal");
}
else
{
return default;
}
}
/// <summary>
/// Generates a detailed account history report showing all transactions with running balance calculations.
/// </summary>
/// <returns>A formatted string containing the complete transaction history with dates, amounts, running balances, and notes.</returns>
/// <remarks>
/// This method creates a formatted report that includes a header row followed by all transactions in chronological order.
/// Each row shows the transaction date (in short date format), the transaction amount, the running balance after that
/// transaction, and any notes associated with the transaction. The running balance is calculated by iterating through
/// all transactions and maintaining a cumulative total. The report uses tab characters for column separation and
/// is suitable for display in console applications or simple text outputs.
/// </remarks>
public string GetAccountHistory()
{
var report = new System.Text.StringBuilder();
decimal balance = 0;
report.AppendLine("Date\t\tAmount\tBalance\tNote");
foreach (var item in _allTransactions)
{
balance += item.Amount;
report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
}
return report.ToString();
}
/// <summary>
/// Performs month-end processing for the account. This virtual method can be overridden in derived classes
/// to implement specific month-end behaviors such as interest calculations, fee assessments, or statement generation.
/// </summary>
/// <remarks>
/// The base implementation of this method does nothing, providing a safe default for basic bank accounts.
/// Derived classes such as savings accounts or checking accounts can override this method to implement
/// account-specific month-end processing. Examples include calculating and applying interest payments,
/// assessing monthly maintenance fees, generating account statements, or performing regulatory compliance checks.
/// This method is typically called by banking systems at the end of each month as part of batch processing operations.
/// </remarks>
public virtual void PerformMonthEndTransactions() { }
}
İşiniz bittiğinde, yeniden oluşturulan XML dosyasını açın ve her üyenin yeni öğelerinizle birlikte göründüğünü onaylayın. Kırpılmış bir bölüm aşağıdaki gibi görünebilir:
<member name="T:OOProgramming.BankAccount">
<summary>Represents a bank account that records transactions and enforces an optional minimum balance.</summary>
<remarks>Account numbers are generated sequentially when each instance is constructed.</remarks>
</member>
<member name="P:OOProgramming.BankAccount.Balance">
<summary>Gets the current balance based on all recorded transactions.</summary>
<value>The net sum of deposits and withdrawals.</value>
</member>
Tip
Özetleri tek bir cümlede tutun. Birden fazla ihtiyacınız varsa, ikincil bağlamı <remarks> içine taşıyabilirsiniz.
Türetilmiş sınıflarda <inheritdoc/> kullanın
Eğer BankAccount öğesinden türetirseniz (örneğin, faiz uygulayan bir SavingsAccount), temel belgeleri kopyalamak yerine devralabilirsiniz. Türetilmiş üyenin belge bloğuna kendi kendini kapatan <inheritdoc/> bir öğe ekleyin. Daha fazla öğe (örneğin, ek <remarks> ayrıntılar), özel davranışı belgelemek için <inheritdoc/>'den sonra ekleyebilirsiniz.
/// <inheritdoc/>
/// <remarks>
/// An interest-earning account is a specialized savings account that rewards customers for maintaining higher balances.
/// Interest is only earned when the account balance exceeds $500, encouraging customers to maintain substantial deposits.
/// The annual interest rate of 2% is applied monthly to qualifying balances, providing a simple savings incentive.
/// This account type uses the standard minimum balance of $0 from the base <see cref="BankAccount"/> class.
/// </remarks>
public class InterestEarningAccount : BankAccount
Uyarı
<inheritdoc/> yinelenenleri azaltır ve temel tür belgelerini daha sonra güncelleştirdiğinizde tutarlılığın korunmasına yardımcı olur.
Genel yüzeyi belgeledikten sonra, cs1591 uyarılarının kalmadığını onaylamak için son bir kez oluşturun. Projeniz artık yararlı IntelliSense ve iş akışlarını yayımlamaya hazır yapılandırılmış bir XML dosyası üretmektedir.
Açıklama eklenmiş örneğin tamamını GitHub'daki dotnet/docs deposunun kaynak klasöründe görebilirsiniz.
Yorumlardan çıktı oluşturma
XML açıklamalarından çıkış oluşturmak için bu araçlardan herhangi birini deneyerek daha fazlasını keşfedebilirsiniz:
- DocFX: DocFX şu anda C#, Visual Basic ve F# destekleyen .NET için bir API belge oluşturucusdur. Ayrıca, oluşturulan başvuru belgelerini özelleştirmenize de olanak tanır. DocFX, kaynak kodunuz ve Markdown dosyalarınızdan statik bir HTML web sitesi oluşturur. DocFX ayrıca şablonlar aracılığıyla web sitenizin düzenini ve stilini özelleştirme esnekliği sağlar. Özel şablonlar da oluşturabilirsiniz.
- Sandcastle: Sandcastle araçları , hem kavramsal hem de API başvuru sayfalarını içeren yönetilen sınıf kitaplıkları için yardım dosyaları oluşturur. Sandcastle araçları komut satırı tabanlıdır ve GUI ön ucu, proje yönetimi özellikleri veya otomatik derleme işlemi içermez. Sandcastle Yardım Dosyası Oluşturucusu, otomatik bir şekilde bir yardım dosyası oluşturmak için tek başına GUI ve komut satırı tabanlı araçlar sağlar. Buna yönelik bir Visual Studio tümleştirme paketi de mevcuttur, böylece yardım projeleri tamamen Visual Studio'dan oluşturulup yönetilebilir.
- Doxygen: Doxygen , belgelenmiş bir kaynak dosya kümesinden çevrimiçi bir belge tarayıcısı (HTML olarak) veya çevrimdışı başvuru kılavuzu (LaTeX'te) oluşturur. RTF (MS Word), PostScript, köprülenmiş PDF, sıkıştırılmış HTML, DocBook ve Unix el ile sayfalarda çıkış oluşturma desteği de vardır. Belgelenmemiş kaynak dosyalardan kod yapısını ayıklamak için Doxygen'i yapılandırabilirsiniz.