トラック
/
C#
C#
/
演習
/
テレメトリの構築
テレメトリの構築

テレメトリの構築

学習演習

はじめに

仮引数

この演習では、メソッドの仮引数の詳細と、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演習で始めたラジコンカーのプロジェクトは順調に進みました(おめでとうございます!)。そして、最近いくつかのスポンサー契約がまとまったおかげで、機能強化に使える予算が確保できました。

予算の一部は、テレメトリーを提供するために使われます。

スポンサーを満足させるために、カーがトラックを周回する間にスポンサー名を表示するパネルが車に取り付けられました。

こうした新しい技術の導入によって、カーのバッテリー寿命が劇的に短くなったことにお気づきでしょう。

1. ラジコンカーにスポンサー名を表示できるようにする

SetSponsors()を実装し、1つまたは複数のスポンサー名を受け取ってカーに保存するようにします。

SetSponsors()メソッドの引数はnullでないことが保証されています。

DisplaySponsor()を実装して、選択したスポンサーを表示します。最初に渡されたスポンサーのsponsorNumは0、2番目は1、というようになります。

var car = RemoteControlCar.Buy();
car.SetSponsors("Exercism", "Walker Industries", "Acme Co.");
var sp2 = car.DisplaySponsor(sponsorNum: 1);
// => "Walker Industries"

2. カーのテレメトリーデータを取得する

RemoteControlCar.GetTelemetryData()メソッドを実装します。

GetTelemetryData()は、バッテリー残量のパーセンテージと走行距離(メートル)をout仮引数を通じて利用できるようにします。

GetTelemetryData()は、serialNum引数が以前に受け取った値より小さい場合に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

3. テレメトリーシステムが1メートルあたりのバッテリー消費量を取得できるように機能を追加する

TelemetryClient.GetBatteryUsagePerMeter()メソッドを実装します。

これはRemoteControlCar.GetTelemetryData()を呼び出します。GetTelemetryData()がfalseを返すか、カーがまだ走行していない場合、このルーチンは"no data"を返します。GetTelemetryData()がtrueを返す場合、"usage-per-meter=BATTERY-USAGE-PER-METER"という形式のメッセージを返します。計算式は、(100から現在のバッテリー残量のパーセンテージを引いた値)をこれまでの走行距離(メートル)で割ったものになります。

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"
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
C# Exercism

テレメトリの構築を始める準備はできましたか?

Exercismに登録すれば、62個のコンセプト178個の演習、そして本物の人間によるメンタリングとともに、C#を学んでマスターできます。すべて無料です。