این تمرین برخی از جزئیات پارامترهای متد و کاربرد آنها در C# را بررسی میکند.
پارامترها اطلاعات را از یک متد فراخوانیکننده به یک متد فراخوانیشده منتقل میکنند.
رفتار پارامترها را میتوان با استفاده از اصلاحکنندههایی مانند ref و out تغییر داد.
پارامتری که اصلاحکنندهی out دارد، یک مقدار را از متد فراخوانیشده به فراخوان بازمیگرداند. این پارامتر را میتوان بدون مقداردهی اولیه به متد فراخوانیشده پاس داد و در هر صورت، درون متد فراخوانیشده طوری با آن رفتار میشود که گویی هنگام ورود، مقداردهی اولیه نشده است. برای درک رفتار و قواعد مربوط به اصلاحکنندههای پارامتر، آسانترین راه، مثالها (پایین را ببینید) و پیامهای کامپایلر است.
void Foo(out int val)
{
val = 42;
}
void Bar(int val)
{
val = 42;
}
int importantValue = 1729;
Foo(out importantValue);
var result = importantValue == 42;
// => true
importantValue = 1729;
Bar(importantValue);
result = importantValue == 1729;
// => true
پارامترهای out باید درون متد فراخوانیشده مقداردهی شوند.
پارامتری که اصلاحکنندهی ref دارد، یک مقدار را به متد فراخوانیشده پاس میدهد. وقتی متد بازمیگردد، فراخوان هر بهروزرسانیای را که متد فراخوانیشده در آن پارامتر انجام داده است، میبیند.
void Foo(ref int val)
{
val *= 7;
}
int importantValue = 6;
Foo(ref importantValue);
return importantValue;
// => 42
ref باید متغیر باشند، زیرا متد فراخوانیشده مستقیماً روی همان پارامتری کار میکند که فراخوان میبیند.out و ref هم در امضای متد فراخوانیشده و هم در محل فراخوانی لازم هستند.پروژهی ماشین کنترلی که در تمرین classes شروع کردید خوب پیش رفت (تبریک!) و به لطف چند قرارداد حمایت مالی اخیر، بودجهای برای بهبودها در نظر گرفته شده است.
بخشی از بودجه صرف فراهم کردن امکاناتی از تلهمتری میشود.
برای اینکه حامیان را راضی نگه دارند، پنلی روی ماشین نصب شده است تا هنگام دور زدن پیست، نام حامیان را نمایش دهد.
خواهید دید که ورود این فناوریهای جدید و شیک، عمر باتری ماشین را بهطور چشمگیری کاهش داده است.
متد SetSponsors() را طوری پیادهسازی کنید که یک یا چند نام حامی بگیرد و آنها را روی ماشین ذخیره کند.
توجه کنید که آرگومان متد SetSponsors() تضمین شده است که null نباشد.
متد DisplaySponsor() را پیادهسازی کنید تا حامی انتخابشده را نمایش دهد. اولین حامیای که پاس داده میشود sponsorNum آن ۰ است، دومی ۱ و به همین ترتیب.
var car = RemoteControlCar.Buy();
car.SetSponsors("Exercism", "Walker Industries", "Acme Co.");
var sp2 = car.DisplaySponsor(sponsorNum: 1);
// => "Walker Industries"
متد RemoteControlCar.GetTelemetryData() را پیادهسازی کنید.
متد GetTelemetryData() باید درصد باتری و مسافت پیمودهشده بر حسب متر را از طریق پارامترهای out در دسترس قرار دهد.
اگر آرگومان serialNum کمتر از مقدار دریافتشدهی قبلی باشد، متد GetTelemetryData() باید false را برگرداند. (مشکلی وجود دارد مبنی بر اینکه چندین گرهی تلهمتری درگیر هستند.) در این حالت، serialNum روی بالاترین serialNum قبلی تنظیم میشود و هم درصد باتری و هم مسافت پیمودهشده بر حسب متر روی -1 قرار میگیرند. اگر فراخوانی موفق باشد، serialNum بیتغییر میماند.
var car = RemoteControlCar.Buy();
car.Drive();
car.Drive();
int serialNum = 4;
car.GetTelemetryData(ref serialNum, out int batteryPercentage, out int distanceDrivenInMeters);
// => true, 4L, 80, 4
serialNum = 1;
car.GetTelemetryData(ref serialNum, out batteryPercentage, out distanceDrivenInMeters);
// => false, 4L, -1, -1
متد TelemetryClient.GetBatteryUsagePerMeter() را پیادهسازی کنید.
این متد، RemoteControlCar.GetTelemetryData() را فراخوانی میکند. اگر GetTelemetryData() مقدار false را برگرداند یا ماشین رانده نشده باشد، این روال باید «no data» را برگرداند. اگر GetTelemetryData() مقدار true را برگرداند، باید پیامی به این شکل برگردانده شود: «usage-per-meter=BATTERY-USAGE-PER-METER». که در آن محاسبه برابر است با (۱۰۰ منهای درصد باتری فعلی) تقسیم بر مسافت پیمودهشده بر حسب متر تا این لحظه.
var car = RemoteControlCar.Buy();
car.Drive();
car.Drive();
var tc = new TelemetryClient(car);
int serialNum = 4;
tc.GetBatteryUsagePerMeter(serialNum);
// => "usage-per-meter=5"
serialNum = 1;
tc.GetBatteryUsagePerMeter(serialNum);
// => "no data"