Helve’s Python memo

Pythonを使った機械学習や最適化の備忘録

Pythonプログラマから見たC#

普段はPythonを使っているが、C#を勉強することになったので、 Pythonプログラマから見た相違点を備忘録として残す。

目次

はじめに

比較した言語のバージョンは以下の通り。

言語 バージョン
Python 3.8.3
C# 8.0

なお、C#を勉強し始めて数週間程度なので、 C#について理解が浅かったり、例外を知らない箇所もあるかと思います。 記事に誤り等ありましたら、コメント欄にてご指摘ください。

コーディング以外の違い

開発環境

Python統合開発環境 (IDE) には、SpyderやPyCharm, Jupyter, Visual Studioなどがある。

一方、C#Microsoftが言語の開発を行っているため、IDEVisual Studioほぼ一択という状況である。 2020年7月4日現在、Visual StudioにはWindows版とMac版が利用できる。 最新のWindows版であるVisual Studio 2019には、 Community, Professional, Enterpriseの3エディションがあり、 個人利用であればCommunityを無償で利用できる、 また、Mac版にはエディションの違いはなく、無償で利用できる。

プログラムの実行形式

Pythonインタープリタ方式の言語であり、 実行時はプログラムの先頭から1行ずつ読み込んで実行される。

一方、C#コンパイル方式の言語である。 しかし、C/C++と異なり、C#コンパイル時には中間言語と呼ばれるものに変換されるだけで、 機械語には変換されない。 中間言語機械語に変換されるのは、プログラムを実行するタイミングである。

また、C#のプログラムは、エントリポイントと呼ばれる箇所から開始される。 エントリポイントはMain()という名前で定義したメソッドになる。

基本的な文法の違い

文末のセミコロンの有無

Pythonではプログラムの文の最後にセミコロン;は必須ではない (ただし、同じ行で複数の文を書く場合には、区切りを示すために必要)。 一方、C#では文末にセミコロンが必須である。

オフサイドルールがない

Pythonではif文, for文や関数定義などの範囲をインデントを使って表現する(オフサイドルール)。 C#ではインデントは可読性を上げる役割しかなく、波括弧{ }でif文などの範囲を定める。

Pythonの例:

for i in range(10):
  (処理)

C#の例:

for (int i; i < 10; i++)
{
  (処理)
}

オブジェクト指向

C#Pythonよりもオブジェクト指向の考え方が強い(と個人的に感じる)。 Pythonの場合、オブジェクト指向的なプログラミングを当然できるが、 クラスを使わないプログラムを書くこともできる。 一方、C#の場合、全ての変数と関数(メソッド)はクラスに属している必要があり、 クラスを理解せずにプログラムを書くことは難しい (さらに、クラスは名前空間に属している必要がある)。

例えば、文字を表示する場合、Pythonではprint関数を使うが、C#ではSystem.Console.WriteLineメソッドを使う。 ここで、System名前空間Consoleはクラス名、WriteLineがメソッド名になる。

変数のスコープ

Pythonでは、関数内で定義された変数はローカル変数となり、 基本的に関数の外からアクセスすることは出来ない。

C#では変数のスコープは{ }で囲まれた中である。 したがって、

static void Main(string[] args)
{
    int a = 1;
    {
        Console.WriteLine($"{a}");
    }
}

は有効だが、以下はコンパイルエラーが出る。

static void Main(string[] args)
{
    {
        int b = 2;
    }
    Console.WriteLine($"{b}"); // {}の外ではbは有効ではない
}

変数の型

変数型の宣言

Pythonでは変数の型を宣言する必要はない。 C#では、全ての変数と、メソッドの戻り値の型を宣言する必要がある。 整数型はint, 小数型はdoubleなどと変数の前に付ける。

C#の例:

int a = 3;
double b = 4.2;

文字列

Pythonではstr型で文字列を扱う。 C#でもほぼ同様のstring型がある。

C#の例:

string st = "abc";
Console.WriteLine(st.Length); // 文字列の長さ(3)を表示

ただし、Pythonではシングルクォーテーションとダブルクォーテーションのどちらで文字列を囲っても良かったが、C#では後者しか使えない。 C#では、char型という1文字だけ格納する型にシングルクォーテーションを使うようになっており、string型と区別されている。

リスト型・辞書型

Pythonでは数値や文字列を混在したリスト型変数、辞書型変数を作成できる。 一方、C#では、1つのリスト型変数、辞書型変数に格納できる型は1種類だけである。 また、リストや辞書は、コレクションクラスと呼ばれている。 リスト配列の使い方の例を以下に示す。

List<int> a = new List<int>(); // 整数型のリストを作成
a.Add(1); // 要素を追加
int cnt = a.Count; // 要素数(1)を取得

Pythonではリストにスライスを使って、例えば5番目から10番目の要素を取得したり、 要素を2つ飛ばしで取得するといったことができる。 一方、C#にはスライスがなく、このような処理を簡単に記述することは難しい。

制御文

Pythonではプログラムの流れを制御するための文としてif, for, whileがある。 C#ではそれらに加えて、foreachとswitch文, doループがある。 以下、両者の主な相違を述べる。

for文・foreach文

前述のように、Pythonではfor文は以下のように書ける。 inの後ろにはイテラブル(繰り返し可能な)オブジェクトを置くと、forの後ろの変数に1つずつ要素が代入される。

for i in range(10):
  (処理)

一方、C#のfor文にはforforeachの2種類がある。 for文は以下のように、カウンターとなる変数、繰り返す条件、1周ごとにカウンター変数に行う操作、 をセミコロン;で区切って書く。

for (int i; i < 10; i++)
{
  (処理)
}

一方、C#foreach文は配列の要素を順に取り出すものであり、Pythonfor文に近い使い方ができる。

int[] a = {0, 1, 2, 3};
foreach (int i in a)
{
  (処理)
}

switch文・doループ

switch文は変数の値によって、処理を分岐させるものである。 処理が複数ある場合には、for文よりも可読性が高い。

doループはwhileループのように、繰り返し処理を行うものである。 相違点は、whileループが内部処理の前にループの脱出判定を行うのに対して、 doループでは内部処理の後にループの脱出判定を行うことである。 すなわち、doループでは最低でも一度は処理が実施されることになる。

その他

インクリメント演算子・デクリメント演算子

C#ではインクリメント演算子++, デクリメント演算子--を使用できる。

C#の例:

int a = 0;
a++; // aを1だけ増加させる

論理演算子

Pythonでは、bool型 (True, False) に対する論理演算子としてand, or, notを使用する。 一方、C#ではbool型をtrue, false(全て小文字)として、論理演算子&, |, !を使用する。

参考

以下の記事では、C#プログラマから見たPythonの特徴を扱っている。

C#からPythonに乗りかえるための両者の比較 - Qiita

また、C#の文法については以下の書籍を参考にさせていただいた。 文法の他にも、簡単なGUIソフトウェアの作り方も扱っている。 プログラム経験ゼロの方には少し難しいかもしれないが、 C#以外のプログラムの経験がある方であれば、取っ掛かりによいと思う。