![見出し画像](https://assets.st-note.com/production/uploads/images/136370698/rectangle_large_type_2_6fa2dc67bbae91d0b05f10bd54a96725.png?width=1200)
C#初心者を卒業しよう(第4回の解答例)
プログラム
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddTransient<DistanceService>()
.AddScoped<ToYards>()
.AddScoped<IDistance, ToYards>()
.AddScoped<ToMeters>()
.AddScoped<IDistance, ToMeters>()
.AddScoped<MetersToFeet>()
.AddScoped<IDistance, MetersToFeet>()
.AddScoped<FeetToMeters>()
.AddScoped<IDistance, FeetToMeters>();
using IHost host = builder.Build();
var service = host.Services.GetService<DistanceService>() ??
throw new NotImplementedException(
"Faild to create 'DistanceService' object.");
service.Run();
public interface IDistance
{
void Calculate(double distance);
string CreateAnswerMessage();
}
public enum ConvertNumber
{
ToYards = 1,
ToMeters = 2,
MetersToFeet = 3,
FeetToMeters = 4,
}
public class DistanceService(IServiceProvider serviceProvider)
{
public void Run()
{
var convertNumber = InputConvertNumber();
var distanceObject = Create(convertNumber) ??
throw new NotImplementedException(
"Faild to create 'IDistance' object.");
var distance = InputDistance();
distanceObject.Calculate(distance);
OutputAnswer(distanceObject);
}
protected virtual ConvertNumber InputConvertNumber()
{
Console.WriteLine("Please input convert number.");
Console.WriteLine(
$"{(int)ConvertNumber.ToYards} : Convert meters to yards.");
Console.WriteLine(
$"{(int)ConvertNumber.ToMeters} : Convert yards to meters.");
Console.WriteLine(
$"{(int)ConvertNumber.MetersToFeet} : Convert meters to feet.");
Console.WriteLine(
$"{(int)ConvertNumber.FeetToMeters} : Convert feet to meters.");
if (Enum.TryParse(
typeof(ConvertNumber),
Console.ReadLine(),
out var convertNumber))
{
return (ConvertNumber)convertNumber;
}
throw new FormatException("Invalid input convert number.");
}
protected virtual IDistance? Create(ConvertNumber convertNumber)
{
switch (convertNumber)
{
case ConvertNumber.ToYards:
return (IDistance?)serviceProvider
.GetService(typeof(ToYards));
case ConvertNumber.ToMeters:
return (IDistance?)serviceProvider
.GetService(typeof(ToMeters));
case ConvertNumber.MetersToFeet:
return (IDistance?)serviceProvider
.GetService(typeof(MetersToFeet));
case ConvertNumber.FeetToMeters:
return (IDistance?)serviceProvider
.GetService(typeof(FeetToMeters));
default:
throw new ArgumentOutOfRangeException(
$"{convertNumber} is out of range.");
}
}
protected virtual double InputDistance()
{
Console.WriteLine("Please input distance.");
if (double.TryParse(Console.ReadLine(), out var distance))
{
return distance;
}
throw new FormatException("Invalid input distance.");
}
protected virtual void OutputAnswer(IDistance distance)
{
var outputMessage = distance.CreateAnswerMessage();
Console.WriteLine(outputMessage);
}
}
public class Const
{
public static readonly double METER_TO_YARD = 1.0936133d;
public static readonly double METER_TO_FOOT = 0.3048d;
}
public class ToYards : IDistance
{
private double _yards;
private double _meters;
public void Calculate(double meters)
{
_meters = meters;
_yards = meters * Const.METER_TO_YARD;
}
public string CreateAnswerMessage()
{
return $"{_meters} meters is {_yards} yards.";
}
}
public class ToMeters : IDistance
{
private double _yards;
private double _meters;
public void Calculate(double yards)
{
_yards = yards;
_meters = yards / Const.METER_TO_YARD;
}
public string CreateAnswerMessage()
{
return $"{_yards} yards is {_meters} meters.";
}
}
public class MetersToFeet : IDistance
{
private double _feet;
private double _meters;
public void Calculate(double meters)
{
_meters = meters;
_feet = meters / Const.METER_TO_FOOT;
}
public string CreateAnswerMessage()
{
return $"{_meters} meters is {_feet} feet.";
}
}
public class FeetToMeters : IDistance
{
private double _feet;
private double _meters;
public void Calculate(double feet)
{
_feet = feet;
_meters = feet * Const.METER_TO_FOOT;
}
public string CreateAnswerMessage()
{
return $"{_feet} feet is {_meters} meters.";
}
}
ダウンロード
解説
列挙(enum)に追加する。
public enum ConvertNumber
{
ToYards = 1,
ToMeters = 2,
MetersToFeet = 3,
FeetToMeters = 4,
}
入力メッセージを追加
Console.WriteLine(
$"{(int)ConvertNumber.MetersToFeet} : Convert meters to feet.");
Console.WriteLine(
$"{(int)ConvertNumber.FeetToMeters} : Convert feet to meters.");
オブジェクト生成を追加
case ConvertNumber.MetersToFeet:
return (IDistance?)serviceProvider
.GetService(typeof(MetersToFeet));
case ConvertNumber.FeetToMeters:
return (IDistance?)serviceProvider
.GetService(typeof(FeetToMeters));
定数を追加
public class Const
{
public static readonly double METER_TO_YARD = 1.0936133d;
public static readonly double METER_TO_FOOT = 0.3048d;
}
変換クラスを追加
メートルをフィートに変換するクラスを追加します。
public class MetersToFeet : IDistance
{
private double _feet;
private double _meters;
public void Calculate(double meters)
{
_meters = meters;
_feet = meters / Const.METER_TO_FOOT;
}
public string CreateAnswerMessage()
{
return $"{_meters} meters is {_feet} feet.";
}
}
フィートをメートルに変換するクラスを追加します。
public class FeetToMeters : IDistance
{
private double _feet;
private double _meters;
public void Calculate(double feet)
{
_feet = feet;
_meters = feet * Const.METER_TO_FOOT;
}
public string CreateAnswerMessage()
{
return $"{_feet} feet is {_meters} meters.";
}
}
DI コンテナに登録
最後に DI コンテナに登録します。
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddTransient<DistanceService>()
.AddScoped<ToYards>()
.AddScoped<IDistance, ToYards>()
.AddScoped<ToMeters>()
.AddScoped<IDistance, ToMeters>()
.AddScoped<MetersToFeet>()
.AddScoped<IDistance, MetersToFeet>()
.AddScoped<FeetToMeters>()
.AddScoped<IDistance, FeetToMeters>();
using IHost host = builder.Build();
よろしければサポートをお願いします。 いただいたサポートは、書籍代、開発機器購入などに充てさせていただきます。