轨道
/
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(),接收一个或多个赞助商名称并把它们存储在汽车上。

注意,SetSponsors()方法的实参保证非空。

实现DisplaySponsor()来显示选中的赞助商。传入的第一个赞助商的sponsorNum为 0,第二个为 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形参提供电池电量百分比和以米为单位的已行驶距离。

如果 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

3. 添加功能,让遥测系统能够获取每米电量消耗

实现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#,全部免费。