ホームに戻る
C#メモ
0、はじめに
C#はJavaに似たプログラム言語です。
Javaとは仕様の違いがあるので、特徴的なところをまとめてみます。
C++ほど奇々怪々ではありませんがJavaほどすっきりしません。
Javaと違ってC#では仮想マシンをVMと呼びません。
.NETフレームワークのCLR(Common Language Runtime)と呼ぶそうです。
1、例文
// Test.cs (拡張子は .cs です。)
// using System; // これで System. を省略できる。
class Test{
private int a = 1; // private などはデータ型の前に 初期化もここで
static int Main(string[] args){ // C#における main です。
Test t = new Test(); // C++と違いポインタ的表現はありません。
System.Console.Write("Te"); // System は namespace。
System.Console.WriteLine("st" + t.a);
System.Console.ReadKey();
// 仮想マシンが解放するので delete はありません。
return 0;
}
}
実行結果
Test1
2、データ型
object型、bool型、string型
などがあります。
ポインタも使える。
列挙型は、
enum NUM : int {A = 0, B, C}
とし、
(int)NUM.A
などとしてアクセスします。
3、const
データ型は const をつけると数値が変更できないのはC++と同じ。
コンストラクタ内でのみ変更ができる readonly というのもある。
class Test{
public const string str1 = "test1"; // static はつけても一緒なのでつけない
public static readonly string str2; // static をつけるかどうかで挙動が変わる
static Test(){
//str1 = "test1"; // 不適切
str2 = "test2"; // 可能
}
static void Main() {
//str2 = "test3"; // 不適切
}
}
4、配列
class Test{
static void Main(){
// int[,] p = new p[3, 2]; // 初期化しない場合
int[,] p = { // [] → [,] → [,,] と次元は増やせる。
{0 , 1},
{2 , 3},
{5 , 7}
};
for (int i = 0; i < p.GetLength(0); i++){ // GetLength で最大数を得る
for (int j = 0; j < p.GetLength(1); j++){
System.Console.WriteLine(p[i, j]);
}
}
}
}
実行結果
0
1
2
3
5
7
また、次のような定義も可能。
int[][] p = new int[3][];
p[0] = new int[] {0, 1};
p[1] = new int[] {2, 3};
p[2] = new int[] {5, 7};
5、構造体
構造体はクラスと違いデータをヒープでなくスタックに置く。
CやC++のものとはまったく別物なので、気を抜くと痛い目にあいそう。
public struct point{
public int x, y; // ここで = 0 などとして初期化できない。
public point(int x, int y){this.x = x; this.y = y;}
public void print(){
System.Console.WriteLine(x + ":" + y);
}
}
class Test{
static void Main(string[] args){
point p1 = new point(); // x や y の初期化は 0 で行われる。
point p2;
point p3 = new point(50, 50);
p1.print();
//p2.print(); // 不適切
p2.x = 20; // 値を入れないとエラー
p2.y = 30; // 値を入れないとエラー
System.Console.WriteLine("{0}:{1}", p2.x, p2.y);
p3.print();
System.Console.ReadKey();
}
}
実行結果
0:0
20:30
50:50
6、算術演算、制御文
算術演算や制御文には大きな違いは無い。
7、internal
コンパイル単位の名前参照を許可し、
リンク単位では外部に名前を参照させない。
class A{
internal void print(){
System.Console.WriteLine("test");
}
}
8、動的引数
動的に引数の個数を変えることができます。
class Test {
public static void print(params int[] p) {
for(int i = 0; i < p.Length; i++){
System.Console.Write(p[i]);
}
System.Console.WriteLine("");
}
static void Main(){
print(0);
print(1, 2, 3);
}
}
実行結果
0
123
9、静的コンストラクタ
C#にもコンストラクタは存在しますが、
C#には static なコンストラクタが認められます。
new などでインスタンスを与える必要はありません。
class St{
static string str = "test";
static St(){}
public static void print(){
System.Console.WriteLine(str);
}
}
class Test_st{
static void Main() {
St.print();
}
}
実行結果
test
10、参照
引数に参照が使えます。
ref と out の使い分けがある点に注意。
class Test{
static void Main() {
int x = 0 , y;
getXY(ref x , out y); // 初期化されているときは ref されていないと out
System.Console.WriteLine(x + ":" + y);
}
static void getXY(ref int x , out int y){
x = 50;
y = 100;
}
}
実行結果
50:100
11、継承
C#では多重継承は禁止されています。
また、メンバの隠蔽は new で明示しないと警告がでます。
class A{
public int num = 0;
public A(int num){this.num = num;}
}
class B : A{ // public な継承しかありません
new public int num = 2; // あえて A の num を隠蔽するので new をつける
public B() : base(1){}
public void print(){
System.Console.WriteLine(base.num + ":" + num); // 親クラスには base でアクセス
}
static void Main(){
B b = new B();
b.print();
}
}
実行結果
1:2
12、仮想関数
C++同様に仮想関数は存在します。
C#では仮想関数をオーバーライドする場合 override を書かないと警告がでます。
class A{
public void f(){
System.Console.WriteLine("A:f");
}
public virtual void vf(){
System.Console.WriteLine("A:vf");
}
}
class B : A{
new public void f(){
System.Console.WriteLine("B:f");
}
public override void vf(){ // override を書くこと
System.Console.WriteLine("B:vf");
}
}
class Test{
static void Main(){
A a1 = new A();
A a2 = new B();
//B b1 = new A(); // 不適切
B b2 = new B();
a1.f();
a1.vf();
a2.f();
a2.vf(); // これは B の vf を呼ぶ
b2.f();
b2.vf();
}
}
実行結果
A:f
A:vf
A:f
B:vf
B:f
B:vf
13、抽象クラス
あえてインスタンスを作れないクラスを抽象クラスと呼ぶ。
abstract class A{
public void f(){
System.Console.WriteLine("A:f");
}
public abstract void af(); // abstract 関数は中身を定義できない。
}
class B : A{
new public void f(){
System.Console.WriteLine("B:f");
}
public override void af(){ // override を書くこと
System.Console.WriteLine("B:af");
}
}
class Test{
static void Main(){
//A a1 = new A(); // 不適切
A a2 = new B();
//B b1 = new A(); // 不適切
B b2 = new B();
a2.f();
a2.af(); // これは B の vf を呼ぶ
b2.f();
b2.af();
}
}
実行結果
A:f
B:af
B:f
B:af
14、シールドクラス
あえて継承させたくないクラスに sealed をつけます。
class の前に sealed をつけると継承するとエラーになります。
また、override した関数をこれ以上オーバーライドさせないように、
関数に対しても sealed override をつけることがあります。
15、インターフェイス
考え方はJavaのものと同じです。
interface C : A, B{} のように結合することも可能です。
interface Print{
void print();
}
class A : Print{
public void print(){
System.Console.WriteLine("A");
}
}
class B : Print{
public void print(){
System.Console.WriteLine("B");
}
}
class Test{
static void Main(){
Print pa = new A();
Print pb = new B();
pa.print();
pb.print();
System.Console.ReadKey();
return 0;
}
}
実行結果
A
B
16、例外
例外は try、throw、catch で特に変わりが無いが、
finally という仕組みが追加されている。
try{
// 失敗する可能性のある処理
}
catch{
// 失敗したときの処理
}
finally {
// 成功しようと失敗しようと最後に通る処理
}
17、桁あふれの監視
checked が有効なブロックでは桁あふれがあると例外が throw されます。
逆に throw させたく無い場合には unchecked をつけます。
checked{
try{
byte x = 255;
x = (byte)(x + 1);
}
catch(System.OverflowException err){
System.Console.WriteLine(err.Message);
}
}
18、デリゲード
関数ポインタのようなもの。
デリゲートは加算していちどに複数の関数も呼べます。
減算して呼ぶ関数を消すこともできるようです。
delegate void Delegate(int a);
class Test{
static void Main(){
Delegate a = new Delegate(A);
a += new Delegate(B);
a(3); // A(3) を呼び、次に B(3) を呼ぶことになる。
}
static void A(int n)
{
System.Console.WriteLine("A:" + n);
}
static void B(int n)
{
System.Console.WriteLine("B:" + n);
}
}
19、イベント
デリゲートの発展系。
関数ポインタをメンバ関数から呼んでいる。
delegate void PrintCallback(int num);
class Print{
private int num;
public event PrintCallback PrintListener;
public Print(int num){this.num = num;}
public void StartEvent(){PrintListener(num);}
}
class Test{
static void Main() {
Print p = new Print(3);
p.PrintListener += new PrintCallback(Action);
//p.KittyListener(); // 不適切
p.StartEvent();
}
static void Action(int num){
System.Console.WriteLine(num);
}
}
実行結果
3
20、数学関数
System.Random や System.Math クラスが用意されている。