「C Sharp」の版間の差分

ナビゲーションに移動 検索に移動
11,068 バイト除去 、 1 か月前
「C Sharp/条件分岐」 のサブページ化。
M (→‎if文: 見出しレベルの修正)
(「C Sharp/条件分岐」 のサブページ化。)
* [[C Sharp/変数]]
* [[C Sharp/クラスとメソッド]]
* [[C Sharp/条件分岐]]
※ 以下、サブページ未作成
* C Sharp/条件分岐
* C Sharp/ループや繰り返し
 
 
数値以外も対応可能な形式として、特に指定のない事を明示する場合、<code> {0:g} </code> のように「:g」をつける方法もあります。一般 general の g です。
 
 
 
=== 条件分岐 ===
==== if文 ====
if文(「イフぶん」と読む)をもちいた処理により、直後の条件を満たした場合にだけブロック内の処理を実行させることができます。ここでいう「ブロック」とは、if文の直後の<code>{</code>から次の<code>}</code>までにある、ひとかたまり(英語でブロック)の処理のことです。
 
C#のif文の記法や使い方は、標準C言語やC++とほぼ同じです。
 
:<syntaxhighlight lang="csharp">
using System;
 
public class Hello {
public static void Main(string[] args) {
 
int a =7;
 
if (a > 5) {
Console.WriteLine("5より大きい");
}
if (a <= 5) {
Console.WriteLine("5以下です");
}
}
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
5より大きい
</syntaxhighlight>
 
言葉で説明するのは難しいので、上記コードを手元の実行環境にコピーして、aの値を色々と変えてみて実験してみましょう。
 
構文としては、
:<syntaxhighlight lang="csharp">
if (条件) {
// 条件が満たされた場合にこのブロックが実行される
}
</syntaxhighlight>
です。
 
if文のあとに<code>else if</code>を使うと、直前のif文が実行されなかった場合にだけ条件判定させることができます。下記のように使います。
 
なお、if のない単独の<code>else</code> は、単に前の条件が満たされなかっただけでもブロック内が実行されます。
 
:<syntaxhighlight lang="csharp">
using System;
 
public class Hello {
public static void Main(string[] args) {
 
int a = +2;
 
if (a > 5) {
Console.WriteLine("5より大きい");
}
else if (a >= 0 && a <= 5) {
Console.WriteLine("0以上かつ5以下です");
}
else {
Console.WriteLine("0未満です");
}
}
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
0以上かつ5以下です
</syntaxhighlight>
 
else if で判定が行われる条件として直前のif文が満たされなかった場合でなければなりません。なので、もし直前のif文が満たされるように条件を書き換えると、else if は実行されなくなります。試してみましょう。
 
下記コードは、やや条件分岐のバグを含んでいます。
 
:<syntaxhighlight lang="csharp">
// 条件分岐にバグあり
using System;
 
public class Hello {
public static void Main(string[] args) {
 
int a = +2;
 
if (a < 5) { // 不等号を逆に書き換えた
Console.WriteLine("5より大きい");
}
else if (a >= 0 && a <= 5) {
Console.WriteLine("0以上かつ5以下です");
}
else {
Console.WriteLine("0未満です");
}
}
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
5より小さい
</syntaxhighlight>
 
「0以上かつ5以下」という条件は満たしているのにもかかわらず、else if の直前のif文が満たされているので、else if のブロックは実行されていません。
 
この例のように、else if は、なれずに使うとバグにつながります。elseの仕組みを正しく理解して、どうしても必要な場合にだけ else if や else を使いましょう。
 
当然ですが、直前にif がないのに else if を使うとエラーになります。また、直前が else で終わってるのに続けてelse if を使ってもエラーになります。また、if と else や else if のあいだに <code>Console.WriteLine(a);</code>など別の命令があってもエラーになります。
 
==== 単なるswitch文 ====
まず、switch文やenumはC#では下記のように使う。.net core 6 で下記コードが動くので、C#10 に対応しているはず。
 
switch文についての説明は省略する。2022年6月現在、まだ当wikiにC#のif文やswitch文の教材は無いので、標準Cなどの解説を参照してもらいたい。
 
※ 下記は .net core でのプログラム
:<syntaxhighlight lang="csharp">
using System;
 
week weekinst = week.Saturday;
 
switch (weekinst) {
 
case week.Saturday:
Console.WriteLine("土曜日");
break;
case week.Sunday:
Console.WriteLine("日曜日");
break;
 
default:
Console.WriteLine("平日");
break;
}
 
enum week {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
土曜日
</syntaxhighlight>
 
 
enumについては、後述する列挙型のセクションを参照せよ。
 
enumを使わなくてもswitch文は書けるが、現代では、なるべくenumを使って書くのが望ましい。
 
 
enum を使わない場合、たとえば下記のように、条件を意味する数値をプログラマー側で決めておいて割り当てをしなければならず、色々と問題がある(プログラマーごとの割り当てルールのバラツキの問題、追加で挿入の条件があると以降の番号を振り直しの問題、など)。
 
:<syntaxhighlight lang="csharp">
using System;
 
public class Hello {
public static void Main(string[] args) {
 
const int Saturday = 0;
const int Sunday = 1;
const int Monday = 2;
const int Tuesday = 3;
// 長いので省略
 
var weekinst = Monday; // とりあえず月曜日
 
switch (weekinst) {
 
case Saturday:
Console.WriteLine("土曜日");
break;
case Sunday:
Console.WriteLine("日曜日");
break;
case Monday:
Console.WriteLine("月曜日");
break;
default:
Console.WriteLine("火曜から金曜");
break;
}
 
}
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
月曜日
</syntaxhighlight>
 
もしenumを使わないと、たとえば「月曜日(Monday)を0にして数え始めたい」とか顧客の要望などが変わった場合、下記コードの部分の番号を振り直しになるのである。このようにenumを使わないと色々と非効率である。
 
:<syntaxhighlight lang="csharp">
const int Saturday = 0;
const int Sunday = 1;
const int Monday = 2;
const int Tuesday = 3;
// 長いので省略
 
</syntaxhighlight>
 
==== switch式 ====
C#7~8 から「switch 式」というのが追加された。下記のような処理ができる。
 
※ 下記は .net core でのプログラム
 
:<syntaxhighlight lang="csharp">
week weekval = week.Saturday;
 
string message = weekval switch { // switch式用のインスタンス的なものを作成しないといけない
 
week.Saturday => "土曜日" ,
 
week.Sunday => "日曜日" ,
 
_ => "平日" , // default に相当
 
};
 
Console.WriteLine(message);
 
 
enum week {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
土曜日
</syntaxhighlight>
 
switch式では条件に「default」は使えない。アンダーバー<code>_</code>で指定した条件以外の値の場合の結果を指定する。
 
C#のコンパイラでは、switch式の全ての値を網羅してないかぎり、アンダーバー<code>_</code>で指定しないと、警告が出る。よって上記のようなコードになる。
 
なお、
week.Saturday =>Console.WriteLine("土曜日"); // エラー
と書いても、うまく行かない。コンパイラにvoid型に変換できないと出るが、しかし
void message = weekval switch { // エラー
などと書き換えてもエラーになる。
 
よって、上記コードのように、switch式の結果(右側)では、命令ではなく値だけを指定して事前に用意された変数に代入することになる。別途、その結果を代入した変数をつかって目的の処理をする命令が必要である。
 
==== 列挙型 ====
条件分岐に限った機能ではないのですが、 enum というキーワードを使う列挙型(Enumeration types)という機能が標準C言語の時代からあり、C++にもC#にもenumがあります。
 
enum は下記のように使います。なおコードはMicrosoft Doc のものを[https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/enum 『列挙型 (C# リファレンス)』2022/04/06]、当wikiで紹介した実行環境でも動くように修正したものです。
 
※ 下記は .net framework および mono のコード
:<syntaxhighlight lang="csharp">
using System;
 
public enum Season
{
Spring,
Summer,
Autumn,
Winter
}
 
public class EnumConversionExample
{
public static void Main()
{
Season a = Season.Autumn;
Console.WriteLine($"Integral value of {a} is {(int)a}"); // output: Integral value of Autumn is 2
 
var b = (Season)1;
Console.WriteLine(b); // output: Summer
 
var c = (Season)4;
Console.WriteLine(c); // output: 4
}
}
 
</syntaxhighlight>
; 実行結果 :<syntaxhighlight lang="text">
Integral value of Autumn is 2
Summer
Winter
</syntaxhighlight>
 
 
まず、C# の enum は、特にクラスで包含する必要はありません。このように enum はC#では特殊なクラスのようなものとして扱われています。
 
enum は、定数のグループを作るためのものであり、ブロック内での定数の宣言順に 0,1,2,3,・・・の定数値を割り当てするものです。なんのためにこれをするかというと、用途は多々考えられますが、よくswitch文への応用が挙げられます。
 
ともかく、enum は広い意味でのクラスの一種なので、要素へのアクセス方法も、<code>Season.Autumn</code>のように
enum型名.変数名
です。なお、enumの要素のことをプログラミング一般で「列挙子」とか「列挙定数」と言います。つまり、
 
:<syntaxhighlight lang="csharp">
public enum 列挙型名
{
列挙子名0,
列挙子名1,
列挙子名2,
列挙子名3
}
</syntaxhighlight>
 
です。
 
広い意味でのクラスの一種と言いましたが、しかしenumはC#よりも昔からあることもあってか、newなどのキーワードによるインスタンスの作成は不要です。そもそも書き換えをしないので、インスタンスの作成は不要です(インスタンスは呼び出し元ごとに書き換えをしたりアレンジしたりするためのものだから)。
 
c# の enum の場合、<code>var b = (Season)1;</code> をenum型名でキャストすることで、割り当て数値→列挙子名への逆引きができます。
 
ですが、列挙子に割り当てられてないものをキャストしようとした場合、そのまま数値が変えされます。割り当てられてない数値が与えられても、そこでプログラムが止まったりはしません。
 
=== 配列 ===
23,090

回編集

案内メニュー