منابع یافتن فایلهای تعاریف نوعها
- بزرگترین مخزن کد فایلهای تعاریف نوعهای TypeScript، در سایت Github و در مخزن کد DefinitelyTyped قابل مشاهده است:
https://github.com/DefinitelyTyped/DefinitelyTyped
- همچنین ابزار دیگری به نام «Typings type definition manager» نیز میتواند برای این منظور بکار رود.
- علاوه بر اینها، بستههای npm نیز میتوانند به همراه تعاریف فایلهای .d.ts باشند.
مفهوم Ambient Modules
پروژههای TypeScript عموما به همراه تعداد زیادی ماژول هستند. به این ترتیب هر ماژول نیاز به d.ts. فایل مخصوص خودش خواهد داشت که نگهداری آنها مشکل خواهد بود. به همین جهت یک Solution متشکل از تعدادی ماژول، میتواند تمام تعاریف نوعها را در یک تک فایل d.ts. نگهداری کند که به آن Ambient Module نیز میگویند. برای نمونه فایل d.ts. ذیل را درنظر بگیرید:
// cardCatalog.d.ts declare module "CardCatalog"{ export function printCard(callNumber: string): void; }
سپس برای استفادهی از این فایل d.ts. خواهیم داشت:
// app.ts /// <reference path="cardCatalog.d.ts" /> import * as catalog from "CardCatalog";
بررسی مخرن DefinitelyTyped
DefinitelyTyped مخزن کد عظیمی از فایلهای تعاریف نوعهای TypeScript است. هرچند دریافت این فایلها از مخزن کد Github آن مانند سایر فایلهای متداول آن سایت، اما چندین روش دیگر نیز برای کار با این مخزن کد وجود دارد:
- استفاده از NuGet. تقریبا تمام فایلهای d.ts. آن به صورت یک بستهی نیوگت مجزا نیز وجود دارند.
- استفاده از برنامهی tsd. این برنامه یا type definition manager، به صورت اختصاصی برای کار با این نوع فایلها طراحی شدهاست.
- استفاده از برنامهی typings. این برنامه نیز یک type definition manager دیگر است. مزیت آن کار با چندین منبع مجزای ارائهی فایلهای d.ts. است که DefinitelyTyped تنها یکی از آنها است.
یک مثال: دریافت مستقیم و افزودن فایل d.ts. مربوط به کتابخانهی جاوا اسکریپتی lodash از مخزن کد DefinitelyTyped
در ادامه قصد داریم فایل تعاریف نوعهای کتابخانهی معروف lodash را به پروژهی جدیدی در VSCode اضافه کنیم. قدم اول، نصب خود کتابخانه است؛ از این جهت که فایلهای d.ts.، فاقد هرگونه پیاده سازی هستند.
در مطلب «چرا TypeScript» نحوهی کار با npm را جهت به روز رسانی کامپایلر TypeScript پیش فرض VSCode ملاحظه کردید. در اینجا نیز از npm برای نصب lodash استفاده میکنیم:
ابتدا خط فرمان را گشوده و سپس به پوشهی پروژهی خود وارد شوید. سپس دو دستور ذیل را صادر کنید:
npm init -f npm install lodash --save
در ادامه به مخزن کد DefinitelyTyped وارد شده و پوشهی مربوط به lodash را با جستجو پیدا کنید:
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/lodash
در این پوشه تنها به فایل lodash.d.ts آن نیاز است. روی لینک این فایل کلیک کرده و سپس در صفحهی باز شده، بر روی دکمهی raw کلیک نمائید. این فایل نهایی را در ریشهی پروژهی جاری ذخیره کنید.
https://github.com/DefinitelyTyped/DefinitelyTyped/raw/master/lodash/lodash.d.ts
اگر به انتهای فایل lodash.d.ts دقت کنید، تعریف ambient module آن چنین شکلی را دارد و export آن lo dash است:
declare module "lodash" { export = _; }
/// <reference path="lodash.d.ts" />
import * as _ from "lodash";
let snakeCaseTitle = _.snakeCase("test this"); console.log(snakeCaseTitle);
برای گرفتن خروجی از این مثال همانند قبل، ابتدا Ctrl+Shift+P را فشرده و سپس انتخاب tasks:Run build task< و در ادامه فشردن F5 برای اجرا برنامه، نیاز است صورت گیرند:
مدیریت فایلهای تعاریف نوعها با استفاده از tsd
tsd یک برنامهی خط فرمان است که کار یافتن و دریافت فایلهای d.ts. را ساده میکند. این برنامه منحصرا با مخزن کد DefinitelyTyped کار میکند و پس از دریافت هر فایل d.ts.، ارجاعی به آنرا در فایل tsd.json در ریشهی پروژه ذخیره میکند. همچنین یک تک فایل tsd.d.ts حاوی تعاریف Triple-Slash Directiveها را نیز تولید میکند که در ادامه میتوان تنها این فایل را به فایلهای مدنظر الحاق کرد.
البته باید دقت داشت که این برنامه در ابتدای سال 2016 منسوخ شده اعلام گردید و با برنامهی typings جایگزین شدهاست؛ هرچند هنوز هم مفید است و قابل استفاده.
روش دریافت tsd را در سایت definitelytyped.org میتوانید مشاهده کنید:
http://definitelytyped.org/tsd
نصب آن نیز به صورت یک بستهی npm است:
npm install tsd -g
https://github.com/Definitelytyped/tsd#readme
برای مثال برای نصب فایل تعاریف نوعهای lodash، ابتدا به پوشهی پروژه از طریق خط فرمان وارد شده و سپس دستور ذیل را صادر کنید:
D:\Prog\1395\VSCodeTypeScript>tsd install lodash --save
[ERR!] Error: connect ECONNREFUSED 10.10.34.36:443
اگر موفق به اجرای این دستور شدید، پوشهی جدید typings در ریشهی پروژه ایجاد خواهد شد. داخل آن فایل tsd.d.ts را نیز میتوان مشاهده کرد که حاوی تعاریف فایلهای نوعهای دریافت شدهاست. از این پس در ابتدای فایلهای ts، بجای تعریف جداگانهی این فایلها، تنها میتوان نوشت:
/// <reference path="./typings/tsd.d.ts" />
مدیریت فایلهای تعاریف نوعها با استفاده از typings
برنامهی typings نیز بسیار شبیه به برنامهی tsd است؛ با این تفاوت که منابع آن منحصر به مخزن کد definitelytyped نیست.
مخزن کد این برنامه در گیتهاب قرار دارد: https://github.com/typings/typings
و نصب آن با استفاده از دستور ذیل است:
npm install typings --global
typings install lodash --ambient --save
typings ERR! caused by Unable to connect to "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/299b5caa22876ef27dc8e9a5b7fd7bf93457b6f4/lodash/lodash-3.10.d.ts" typings ERR! caused by connect ECONNREFUSED 10.10.34.36:443
/// <reference path="./typings/main.d.ts" />
Get-Process | Where-Object { $_.Name -eq 'Dropbox' }
PS /Users/sirwanafifi/Desktop> $block = { >> $newVar = 10 >> Write-Host $newVar >> }
PS /Users/sirwanafifi/Desktop> & $block
PS /Users/sirwanafifi/Desktop> & "Get-Process"
PS /Users/sirwanafifi/Desktop> & "1 + 1" or PS /Users/sirwanafifi/Desktop> & "Get-Process -Name Slack"
Function Add-Something { Write-Host "$_ World" } "Hello" | Add-Something
Function Add-Something { [CmdletBinding()] Param( [Parameter(ValueFromPipeline = $true)] [string]$Name ) Write-Host "$Name World" } "Hello" | Add-Something
$API_KEY = "...." Function Read-WeatherData { [CmdletBinding()] Param( [Parameter(ValueFromPipeline = $true)] [string]$CityName ) $Url = "https://api.openweathermap.org/data/2.5/forecast?q=$CityName&cnt=40&appid=$API_KEY&units=metric" Try { Write-Verbose "Reading weather data for $CityName" $Response = Invoke-RestMethod -Uri $Url $Response.list | ForEach-Object { Write-Verbose "Processing $($_.dt_txt)" [PSCustomObject]@{ City = $Response.city.name DateTime = [DateTime]::Parse($_.dt_txt) Temperature = $_.main.temp Humidity = $_.main.humidity Pressure = $_.main.pressure WindSpeed = $_.wind.speed WindDirection = $_.wind.deg Cloudiness = $_.clouds.all Weather = $_.weather.main WeatherDescription = $_.weather.description } } | Where-Object { $_.DateTime.Date -eq (Get-Date).Date } Write-Verbose "Done processing $CityName" } Catch { Write-Error $_.Exception.Message } }
Read-WeatherData -CityName "London" -Verbose
PS /> [Parameter]::new() ExperimentName : ExperimentAction : None Position : -2147483648 ParameterSetName : __AllParameterSets Mandatory : False ValueFromPipeline : False ValueFromPipelineByPropertyName : False ValueFromRemainingArguments : False HelpMessage : HelpMessageBaseName : HelpMessageResourceId : DontShow : False TypeId : System.Management.Automation.ParameterAttribute
Function Ping-Website { [CmdletBinding()] Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidatePattern('^www\..*')] [string[]]$Websites, [ValidateRange(1, 3)] [int]$Count = 3 ) $Results = @() $Websites | ForEach-Object { $Website = $_ $Result = Test-Connection -ComputerName $Website -Count $Count -Quiet $ResultText = $Result ? 'Success' : 'Failed' $Results += @{ Website = $Website Result = $ResultText } Write-Verbose "The result of pinging $Website is $ResultText" } $Results | ForEach-Object { $_ | Select-Object @{ Name = "Website"; Expression = { $_.Website }; }, @{ Name = "Result"; Expression = { $_.Result }; }, @{ Name = "Number Of Attempts"; Expression = { $Count }; } } }
Function Ping-Website { [CmdletBinding()] Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateScript({ If (-Not ($_ | Test-Path) ) { Throw "File or folder does not exist" } If (-Not ($_ | Test-Path -PathType Leaf) ) { Throw "The Path argument must be a file. Folder paths are not allowed." } If ($_ -NotMatch "(\.json)$") { throw "The file specified in the path argument must be either of type json" } Return $true })] [Alias("src", "source", "file")] [System.IO.FileInfo]$Path, [int]$Count = 1 ) $Results = [System.Collections.ArrayList]@() $Urls = Get-Content -Path $Path | ConvertFrom-Json $Urls | ForEach-Object -Parallel { $Website = $_.url $Result = Test-Connection -ComputerName $Website -Count $using:Count -Quiet $ResultText = $Result ? 'Success' : 'Failed' $Item = @{ Website = $Website Result = $ResultText } $null = ($using:Results).Add($Item) } $Results | ForEach-Object -Parallel { $_ | Select-Object @{ Name = "Website"; Expression = { $_.Website }; }, @{ Name = "Result"; Expression = { $_.Result }; }, @{ Name = "Number Of Attempts"; Expression = { $using:Count }; } } }
Function Ping-Website { [CmdletBinding()] Param( # As before ) # As before $Urls | ForEach-Object -Parallel { $DebugPreference = $using:DebugPreference $VerbosePreference = $using:VerbosePreference $InformationPreference = $using:InformationPreference # As before } # As before }
$scriptBlock = { $logOutput = { param($message) Write-Host $message } [int]$someVariable = 10 $doSomeWork = { & $logOutput -message "Some variable value: $someVariable" } $someVariable = 20 & $doSomeWork }
$scriptBlock = { $logOutput = { param($message) Write-Host $message } [int]$someVariable = 10 $doSomeWork = { & $logOutput -message "Some variable value: $someVariable" }.GetNewClosure() $someVariable = 20 & $doSomeWork }
begin process end dynamicparam
function Show-Pipeline { begin { Write-Host "Pipeline start" } process { Write-Host "Pipeline process $_" } end { Write-Host "Pipeline end $_" } }
PS /> 1..2 | Show-Pipeline Pipeline start Pipeline process 1 Pipeline process 2 Pipeline end 2
PS /> "www.google.com", "www.yahoo.com" | Ping-Website Website Result Number Of Attempts ------- ------ ------------------ www.yahoo.com Success 3
Function Ping-Website { [CmdletBinding()] Param( # As before ) process { # As before } }
PS /> "www.google.com", "www.yahoo.com" | Ping-Website Website Result Number Of Attempts ------- ------ ------------------ www.google.com Success 3 www.yahoo.com Success 3
PS /> Read-Csv ./users.csv -Columns name
using namespace System.Management.Automation Function Read-Csv { Param ( [Parameter(Mandatory = $true, Position = 0)] [string]$Path ) DynamicParam { $firstLine = Get-Content $Path | Select-Object -First 1 [String[]]$headers = $firstLine -split ', ' $parameters = [RuntimeDefinedParameterDictionary]::new() $parameter = [RuntimeDefinedParameter]::new( 'Columns', [String[]], [Attribute[]]@( [Parameter]@{ Mandatory = $false; Position = 1 } [ValidateSet]::new($headers) ) ) $parameters.Add($parameter.Name, $parameter) Return $parameters } Begin { $csvContent = Import-Csv $Path If ($PSBoundParameters.ContainsKey('Columns')) { $columns = $PSBoundParameters['Columns'] $csvContent | Select-Object -Property $columns } Else { $csvContent } } }
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found. To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'. For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
Secure Connection Failed An error occurred during a connection to localhost:5001. Certificate key usage inadequate for attempted operation. Error code: SEC_ERROR_INADEQUATE_KEY_USAGE
dotnet dev-certs https --clean dotnet dev-certs https --trust
0. Validation 1. Insert 2. Edit 3. Delete 4. Select
public abstract class PageStateMachine : Page { ... protected abstract ... Save(); protected abstract ... Select(); protected abstract ... Delete(); protected abstract ... Validation(); ...
public enum PageState { Save = 0, Select = 2, Delete = 8, Cancel = 16 }
public void Go(PageState pageState) { switch (pageState) { case PageState.Save: { var error = Validation(); Message = error.HasError ? error.Message : Save().Message; if (!error.HasError) { ClearControls(); RefreshList(); } break; } case PageState.Select: { Message = Select().Message; break; } break; case PageState.Delete: { Message = Delete().Message; ClearControls(); RefreshList(); break; } case PageState.Cancel: { Message = string.Empty; ClearControls(); break; } } }
در پروژههای ویندوزی یکی از بیشترین ابزار کاربردی گریدویو تلریک Telerik
GridView میباشد و اینکه تمامی امکانات گرید مانند گروه بندی ، فیلترینگ و
... همه فارسی باشند خیلی برای پروژه خوب است.
منم در یکی از پروژهها نیاز به فارسی کردن این ابزار پرکاربرد ویندوزی داشتم و توانستم این مورد
را حل کنم . نحوه فارسی کردن این ابزار به شرح ذیل میباشد:
1- یک پروژه جدید ویندوزی در visual studio ایجاد میکنیم
2- اضافه کردن یک radGridView به فرم و خاصیت Dock آن را به حالت Fill و خاصیت RightToLeft را Yes قرار میدهیم :
3- حال برای اینکه یک سری اطلاعاتی داخل این گرید نمایش بدهیم یک کلاس در همان فرم درست میکنیم مشابه کد ذیل :
public List<MyCustomData> GetData() { List<MyCustomData> myList = new List<MyCustomData>(); for (int i = 1; i < 11; i++) { myList.Add(new MyCustomData() { ID = i, Name = "Name Family " + i.ToString(), Age = 29 }); } return myList; } public class MyCustomData { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public bool Sex { get; set; } }
4 - حال برای اینکه این اطلاعات را در گرید نمایش دهیم کد زیر را در بخش Load_Form1 مینویسیم :
private void Form1_Load(object sender, EventArgs e) { radGridView1.DataSource = GetData(); }
6 - برای اینکه این موارد فارسی شوند نیاز به یک کلاس یا Provider داریم که این عمل ترجمه را انجام دهد که حتی در سایت خود تلریک در بخش مربوطه نیز ارائه شده است. بنده این کلاس را کپی کرده و تمامی ترجمههای آنها را نیز نوشتم ( اگر در ترجمه ایرادی بود به بزرگی خودتان بخشیده و تصحیح نمائید . ) که کد آن را در زیر میتوانید در اختیار داشته باشید:
class PersianRadGridLocalizationProvider : RadGridLocalizationProvider { public override string GetLocalizedString(string id) { switch (id) { case RadGridStringId.FilterFunctionBetween: return "بین"; //Between case RadGridStringId.FilterOperatorBetween: return "بین"; case RadGridStringId.FilterFunctionContains: return "حاوی"; case RadGridStringId.FilterOperatorContains: return "حاوی"; case RadGridStringId.FilterFunctionDoesNotContain: return "شامل نشود"; //Does not contain case RadGridStringId.FilterOperatorDoesNotContain: return "شامل نشود"; case RadGridStringId.FilterFunctionEndsWith: return "پایان پذیرد با"; //Ends with case RadGridStringId.FilterOperatorEndsWith: return "پایان پذیرد با"; case RadGridStringId.FilterFunctionEqualTo: return "برابر با"; //Equals case RadGridStringId.FilterOperatorEqualTo: return "برابر با"; case RadGridStringId.FilterFunctionGreaterThan: return "بزرگتر از"; //Greater than case RadGridStringId.FilterOperatorGreaterThan: return "بزرگتر از"; case RadGridStringId.FilterFunctionGreaterThanOrEqualTo: return "بزرگتر یا مساوی با"; //Greater than or equal to case RadGridStringId.FilterOperatorGreaterThanOrEqualTo: return "بزرگتر یا مساوی با"; case RadGridStringId.FilterFunctionIsEmpty: return "خالی باشد"; //Is empty case RadGridStringId.FilterOperatorIsEmpty: return "خالی باشد"; case RadGridStringId.FilterFunctionIsNull: return "تهی باشد"; //Is null case RadGridStringId.FilterOperatorIsNull: return "تهی باشد"; case RadGridStringId.FilterFunctionLessThan: return "کمتر از"; //Less than case RadGridStringId.FilterOperatorLessThan: return "کمتر از"; case RadGridStringId.FilterFunctionLessThanOrEqualTo: return "کمتر یا مساوی با"; //Less than or equal to case RadGridStringId.FilterOperatorLessThanOrEqualTo: return "کمتر یا مساوی با"; case RadGridStringId.FilterFunctionNoFilter: return "بدون شرط"; //No filter case RadGridStringId.FilterOperatorNoFilter: return "بدون شرط"; case RadGridStringId.FilterFunctionNotBetween: return "نباشد بین"; //Not between case RadGridStringId.FilterOperatorNotBetween: return "نباشد بین"; //Operator case RadGridStringId.FilterFunctionNotEqualTo: return "برابر نباشد با"; //Not equal to case RadGridStringId.FilterOperatorNotEqualTo: return "برابر نباشد با"; case RadGridStringId.FilterFunctionNotIsEmpty: return "خالی نباشد"; //Is not empty case RadGridStringId.FilterFunctionNotIsNull: return "خالی نباشد"; //Is not null case RadGridStringId.FilterFunctionStartsWith: return "شروع شود با"; //Starts with case RadGridStringId.FilterFunctionCustom: return "شرط دلخواه"; //Custom case RadGridStringId.CustomFilterMenuItem: return "شرط دلخواه منو"; //Custom case RadGridStringId.CustomFilterDialogCaption: return "انتخاب شرط دلخواه"; //RadGridView Custom Filter Dialog case RadGridStringId.CustomFilterDialogLabel: return ":نشان دادن سطرهایی که"; //Show rows where: case RadGridStringId.CustomFilterDialogRbAnd: return "و"; //And case RadGridStringId.CustomFilterDialogRbOr: return "یا"; //Or case RadGridStringId.CustomFilterDialogBtnOk: return "تایید"; //OK case RadGridStringId.CustomFilterDialogBtnCancel: return "انصراف"; //Cancel case RadGridStringId.AddNewRowString: return "برای افزودن سطر جدید اینجا کلیک کنید"; case RadGridStringId.ClearValueMenuItem: return "پاک کردن مقدار سلول"; case RadGridStringId.DeleteRowMenuItem: return "حذف سطر"; //Delete Row case RadGridStringId.SortAscendingMenuItem: return "مرتب سازی صعودی"; //Sort Ascending case RadGridStringId.SortDescendingMenuItem: return "مرتب سازی نزولی"; //Sort Descending case RadGridStringId.ClearSortingMenuItem: return "حذف مرتب سازی"; //Clear Sorting case RadGridStringId.ConditionalFormattingMenuItem: return "قالب بندی مشروط"; //Conditional Formatting case RadGridStringId.GroupByThisColumnMenuItem: return "گروهبندی بر حسب این ستون"; //Group by this column case RadGridStringId.UngroupThisColumn: return "حذف این ستون از گروهبندی "; //Ungroup this column case RadGridStringId.ColumnChooserMenuItem: return "انتخابگر ستون"; //Column Chooser case RadGridStringId.HideMenuItem: return "مخفی کردن ستون"; //Hide case RadGridStringId.UnpinMenuItem: return "حالت پیش فرض"; //Unpin case RadGridStringId.PinMenuItem: return "حالت ستون"; //Pin case RadGridStringId.PinAtLeftMenuItem: return "چسپیدن به سمت چپ"; case RadGridStringId.PinAtRightMenuItem: return "چسپیدن به سمت راست"; case RadGridStringId.PinAtTopMenuItem: return "چسپیدن به بالا"; case RadGridStringId.PinAtBottomMenuItem: return "چسپیدن به پایین"; case RadGridStringId.BestFitMenuItem: return "اندازه بهینه ستون"; //Best Fit case RadGridStringId.PasteMenuItem: return "چسپاندن"; //Paste case RadGridStringId.EditMenuItem: return "ویرایش"; //Edit case RadGridStringId.CopyMenuItem: return "کپی"; //Copy case RadGridStringId.ConditionalFormattingCaption: return "قالب بندی مشروط"; //Custom Formatting Condition Editor case RadGridStringId.ConditionalFormattingLblColumn: return "قالب بندی سلولهایی با شرط:"; //Column: case RadGridStringId.ConditionalFormattingLblName: return "نام شرط:"; //Name: case RadGridStringId.ConditionalFormattingLblType: return "مقدار سلول:"; //Type: case RadGridStringId.ConditionalFormattingLblValue1: return "مقدار اول:"; //Value 1: case RadGridStringId.ConditionalFormattingLblValue2: return "مقدار دوم:"; //Value 2: case RadGridStringId.ConditionalFormattingGrpConditions: return "شرایط"; //Conditions case RadGridStringId.ConditionalFormattingGrpProperties: return "مشخصات"; //Properties case RadGridStringId.ConditionalFormattingChkApplyToRow: return "اعمال این شرط به کل سطر"; //Apply to row case RadGridStringId.ConditionalFormattingBtnAdd: return "افزودن شرایط"; //Add case RadGridStringId.ConditionalFormattingBtnRemove: return "حذف شرایط انتخابی"; //Remove case RadGridStringId.ConditionalFormattingBtnOK: return "تایید"; //OK case RadGridStringId.ConditionalFormattingBtnCancel: return "انصراف"; //Cancel case RadGridStringId.ConditionalFormattingBtnApply: return "اعمال قالب بندی"; //Apply case RadGridStringId.ColumnChooserFormCaption: return "انتخاب ستون ها"; //Column Chooser case RadGridStringId.ColumnChooserFormMessage: return "برای حذف یکی از ستونها، آن ستون را به اینجا بکشید";//"Drag a column header from the grid here to remove it from the current view."; case RadGridStringId.CompositeFilterFormErrorCaption: return "خطا"; case RadGridStringId.ConditionalFormattingChooseOne: return "[یکی را انتخاب کنید]"; case RadGridStringId.ConditionalFormattingContains: return "[حاوی [مقدار اول"; case RadGridStringId.ConditionalFormattingDoesNotContain: return "حاوی [مقدار اول] نباشد"; case RadGridStringId.ConditionalFormattingEndsWith: return "با [مقدار اول] پایان یابد"; case RadGridStringId.ConditionalFormattingEqualsTo: return "[برابر با [مقدار اول"; case RadGridStringId.ConditionalFormattingIsBetween: return "بین [مقدار اول] و [مقدار دوم] باشد"; case RadGridStringId.ConditionalFormattingIsGreaterThan: return "[بزرگتر از [مقدار اول"; case RadGridStringId.ConditionalFormattingIsGreaterThanOrEqual: return "[بزرگتر یا مساوی با [مقدار اول"; case RadGridStringId.ConditionalFormattingIsLessThan: return "کوچکتر از [مقدار اول]"; case RadGridStringId.ConditionalFormattingIsLessThanOrEqual: return "کوچکتر یا مساوی با [مقدار اول]"; case RadGridStringId.ConditionalFormattingIsNotBetween: return "بین [مقدار اول] و [مقدار دوم] نباشد"; case RadGridStringId.ConditionalFormattingIsNotEqualTo: return "برابر با [مقدار اول] نباشد"; case RadGridStringId.ConditionalFormattingRuleAppliesOn: return "اعمال شرایط روی:"; case RadGridStringId.ConditionalFormattingStartsWith: return "با [مقدار اول] شروع میشود"; case RadGridStringId.CustomFilterDialogCheckBoxNot: return "با این شرایط نباشد"; case RadGridStringId.CustomFilterDialogFalse: return "False"; case RadGridStringId.CustomFilterDialogTrue: return "True"; case RadGridStringId.FilterCompositeNotOperator: return "نباشد"; case RadGridStringId.FilterLogicalOperatorAnd: return "و"; case RadGridStringId.FilterLogicalOperatorOr: return "یا"; case RadGridStringId.FilterMenuAvailableFilters: return "فیلتر شده"; case RadGridStringId.FilterMenuButtonCancel: return "انصراف"; case RadGridStringId.FilterMenuButtonOK: return "تایید"; case RadGridStringId.FilterMenuClearFilters: return "پاک کردن فیلتر"; case RadGridStringId.FilterMenuSearchBoxText: return "جستجو..."; case RadGridStringId.FilterMenuSelectionAll: return "همه"; //case RadGridStringId.FilterMenuSelectionAllSearched: return "نتیجه همه جستجو"; case RadGridStringId.FilterMenuSelectionNotNull: return "خالی نباشد"; case RadGridStringId.FilterMenuSelectionNull: return "خالی باشد"; case RadGridStringId.FilterOperatorCustom: return "دلخواه"; case RadGridStringId.FilterOperatorIsLike: return "مانند"; case RadGridStringId.FilterOperatorNotIsContainedIn: return "نباشد در"; case RadGridStringId.FilterOperatorNotIsEmpty: return "خالی نباشد"; case RadGridStringId.FilterOperatorNotIsLike: return "نباشد شبیه"; case RadGridStringId.FilterOperatorNotIsNull: return "خالی نباشد"; case RadGridStringId.FilterOperatorStartsWith: return "شروع شود با"; case RadGridStringId.GroupingPanelDefaultMessage: return "برای گروهبندی ستونها، ستونی را به اینجا بکشید"; case RadGridStringId.GroupingPanelHeader: return ":گروهبندی بر حسب"; case RadGridStringId.NoDataText: return "داده ای برای نمایش وجود ندارد"; case RadGridStringId.UnpinRowMenuItem: return "حالت پیش فرض"; default: return base.GetLocalizedString(id); } } }
7 - حال اگر برنامه را اجرا کنید باز موارد انگلیسی گرید تلریک فارسی نمیشوند و باید در کلاس Program.cs پروژه این یک خط کد را هم اضافه نمائید.
//using Telerik.WinControls.UI.Localization; RadGridLocalizationProvider.CurrentProvider = new PersianRadGridLocalizationProvider();
8 - حال اگر برنامه را اجرا نمایید تمامی موارد را فارسی مشاهده خواهید نمود ( شکل ذیل )
لطفا ما را از نظرات سازنده خود بی نصیب نفرمائید. با تشکر
- چرا به کامنت گذاری یا مستند نویسی نیاز داریم؟
- چگونه کامنت بنویسیم؟
- انواع کامنتها چیست؟
- چه کامنتهایی اشتباه هستند؟
همانطور که بیان کردیم، کامنت گذاری یکی از مهمترین کارهایی است که یک برنامه نویس انجام میدهد. به خصوص زمانیکه به صورت تیمی کار میکنید، این امر مهمتر از قبل خود را نشان میدهد. بسیاری از برنامه نویسان که بیشتر دلیل آن تنبلی است، از این کار سرباز میزنند و ممکن است آن را اتلاف وقت بدانند. ولی با کامنت گذاری فهم و درک کد، در آینده بالاتر میرود. در مقالهی تخصصی «هنر کامنت نویسی» نوشتهی «برنهارد اسپویدا» بهانههای جالبی از برنامه نویسان را برای سرباز زدن از اینکار، ذکر شده است؛ به عنوان نمونه:
من کدم را به خوبی متوجه میشوم.کد خوب، خودش گویای همه چیز هست.وقتی برای کامنت نویسی وجود ندارد. باید چسبید به کد.
- شاید امروز معنای یک کد را متوجه شوید، ولی آیا در آینده، مثلا یک سال بعد هم چنین خواهد بود؟
- آیا میتوانید هر سیستمی را که طراحی میکنید، به خاطر بسپارید که فعالیتهایش را به چه نحوی انجام میدهد؟
- اگر در یک کار تیمی باشید، شاید شما متوجه کدتان میشوید، ولی آیا تضمینی وجود دارد که دیگران هم متوجه روش شما شوند؟
- آیا کدی که شما بر روی آن فکر کردهاید و در ذهن خود روش انجام آن را ترسیم کردهاید، میتواند برای برنامه نویسی که کد شما را میبیند هم رخ دهد؟
- اگر شما به صورت تیمی کاری را انجام دهید و یکی از برنامه نویسهای شما از تیم جدا شود، چگونه میتوانید کار او را دنبال کنید؟
- اگر برای برنامه نویسی اتفاق یا حادثهای پیش بیاید که دسترسی شما به او ممکن نباشد چه؟
Documentary Comments: این مستند سازی در سطح یک سند مثل فایل یا به خصوص یک پروژه رخ میدهد که شامل اطلاعات و تاریخچهی آن سند است که این اطلاعات به شرح زیر هستند:
File Name | نام سند |
File Number/Version Number | شماره نسخه آن سند |
Creation Date | تاریخ ایجاد آن |
Last Modification Date | تاریخ آخرین تغییر سند |
Author's Name | سازندهی سند |
Copyright Notice | اطلاعاتی در مورد کپی رایت سند |
Purpose Of Program | هدف کاری برنامه. یک خلاصه از آن چه برنامه انجام میدهد. |
Change History | لیستی از تغییرات مهمی که در جریان ایجاد آن رخ داده است. |
Dependencies | وابستگیهای سند. بیشتر در سطح پروژه معنا پیدا میکند؛ مانند نمونهی آن برای سایت جاری که به صورت عمومی منتشر شده است. |
Special Hardware Requirements | سخت افزار مورد نیاز برای اجرای برنامه. حتی قسمتی میتواند شامل نیازمندیهای نرم افزاری هم باشد. |
PCMBOAT5.PAS************************************************************* ** File: PCMBOAT5.PAS Author: B. Spuida Date: 1.5.1999 Revision: 1.1 PCM-DAS08 and -16S/12 are supported. Sorting routine inserted. Set-files are read in and card as well as amplification factor are parsed. 1.1.1 Standard deviation is calculated. 1.1.2 Median is output. Modal value is output. 1.1.4 Sign in Set-file is evaluated. Individual values are no longer output. (For tests with raw data use PCMRAW.EXE) To do: outliers routine to be revised. Statistics routines need reworking. Existing Datafile is backed up. Purpose: Used for measurement of profiles using the Water-SP-probes using the amplifier andthe PCM-DAS08-card, values are acquired with n = 3000. Measurements are taken in 1 second intervals. The values are sorted using Quicksort and are stacked "raw" as well as after dismissing the highest and lowest 200 values as 'outliers'. Requirements: The Card must have an A/D-converter. Amplifier and probes must be connected. Analog Signal must be present. CB.CFG must be in the directory specified by the env-Variable "CBDIREC" or in present directory.
در بالا، خصوصیت کپی رایت حذف شده است. دلیل این امر این است که این برنامه برای استفاده در سطح داخلی یک شرکت استفاده میشود.
Functional Comments: کامنت نویسی در سطح کاربردی به این معنی نیست که شما اتفاقاتی را که در یک متد یا کلاس یا هر بخشی روی میدهد، خط به خط توضیح دهید؛ بلکه چرخهی کاری آن شی را هم توضیح بدهید کفایت میکند. این مورد میتواند شامل این موارد باشد:
- توضیحی در مورد باگهای این قسمت
- یادداشت گذاری برای دیگر افراد تیم
- احتمالاتی که برای بهبود ویژگیها و کارایی کد وجود دارد.
Explanatory Comment: کامنت گذاری توصیفی در سطح کدنویسی رخ میدهد و شامل توضیح در مورد کارکرد یک شیء و توضیح کدهای شیء مربوطه میگردد. برای قرار دادن کامنت الزامی نیست که کدها را خط به خط توضیح دهید یا اینکه خطوط ساده را هم تشریح کنید؛ بلکه کامنت شما همینقدر که بتواند نحوهی کارکرد هر چند خط کد مرتبط به هم را هم توضیح دهد، کافی است. این توضیحها بیشتر شامل موارد زیر میشوند:
- کدهای آغازین
- کدهای خروجی
- توضیح کوتاه از آنچه که این شیء ، متد یا ... انجام میدهد.
- حلقههای طولانی یا پیچیده
- کدهای منطقی عجیب و پیچیده
- Regular Expression
کدهای آغازین شروع خوبی برای تمرین خواهند بود. به عنوان نمونه اینکه توضیحی در مورد ورودی و خروجی یک متد بدهید که آرگومانهای ورودی چه چیزهایی هستند و چه کاربری داردند و در آغاز برنامه، برنامه چگونه آماده سازی و اجرا میشود. مقادیر پیش فرض چه چیزهایی هستند و پروژه چگونه تنظیم و مقداردهی میشود.
کدهای خروجی هم به همین منوال است. خروجیهای نرمال و غیرنرمال آن چیست؟ کدهای خطایی که ممکن است برگرداند و ... که باید به درستی توضیح داده شوند.
توضیح اشیاء و متدها و ... شامل مواردی چون: هدف از ایجاد آن، آرگومان هایی که به آن پاس میشوند و خروجی که میدهد و اینکه قالب یا فرمت آنها چگونه است و چه محدودیتهایی در مقادیر قابل انتظار وجود دارند. ذکر محدودیتها، مورد بسیاری مهمی است و دلیل بسیاری از باگها، عدم توجه یا اطلاع نداشتن از وجود این محدودیت هاست. مثلا محدودهی خاصی برای آرگومانهای ورودی وجود دارد؟ چه اتفاقی میافتد اگر به یک بافر 128 کاراکتری، 1024 کاراکتر را ارسال کنیم؟
کدهای منطقی عجیب، یکی از حیاتیترین بخشهای کامنت گذاری برای نگه داری یک برنامه در آینده است. به عنوان نمونه استفاده از عبارات با قاعده، اغلب اوقات باعث سردرگمی کاربران شده است. پس توضیح دادن در مورد این نوع کدها، توصیه زیادی میشود. اگر عبارات با قاعده شما طولانی هستند، سعی کنید از هم جدایشان کنید یا خطوط آن را بشکنید و هر خط آن را توضیح دهید.
هر زبانی از یک سیستم خاص برای کامنت گذاری استفاده میکند. به عنوان مثال پرل از سیستم (POD (Plain Old Documentation استفاده میکند یا برای Java سیستم JavaDoc یا برای PHP از سیستم PHPDoc (+ ) که پیاده سازی از JavaDoc میباشد استفاده میکنند. این سیستم برای سی شارپ استفاده از قالب XML است. کد زیر نمونهای از استفاده از این سیستم است:
// XMLsample.cs // compile with: /doc:XMLsample.xml using System; /// <summary> /// Class level summary documentation goes here.</summary> /// <remarks> /// Longer comments can be associated with a type or member /// through the remarks tag</remarks> public class SomeClass { /// <summary> /// Store for the name property</summary> private string myName = null; /// <summary> /// The class constructor. </summary> public SomeClass() { // TODO: Add Constructor Logic here } /// <summary> /// Name property </summary> /// <value> /// A value tag is used to describe the property value</value> public string Name { get { if (myName == null) { throw new Exception("Name is null"); } return myName; } } /// <summary> /// Description for SomeMethod.</summary> /// <param name="s"> Parameter description for s goes here</param> /// <seealso cref="String"> /// You can use the cref attribute on any tag to reference a type or member /// and the compiler will check that the reference exists. </seealso> public void SomeMethod(string s) { } }
دستورات سیستم کامنت گذاری سی شارپ
در سایت جاری، دو مقاله زیر اطلاعاتی در رابطه با نحوهی کامنت گذاری ارئه دادهاند.
- در مقاله «زیباتر کد بنویسیم» چند مورد آن به این موضوع اختصاص دارد.
- مقاله «وادار کردن خود به کامنت نوشتن» گزینهی کامنت گذاری اجباری در ویژوال استودیو را معرفی میکند.