|

|
|
目次
|
| 1 |
HelloWorld! |
2002/3/2 |
おきまりのHelloWorld! |
| 2 |
HelloWorld 2 |
2002/3/2 |
DLLを使う |
| 3 |
環境変数の扱い |
2002/3/2 |
環境変数を扱う3つの方法 |
| 4 |
日時の取得 |
2002/3/2 |
日時の取得方法(System.DateTime) |
| 5 |
Garbage Collection |
2002/3/2 |
ガベージコレクションについて(System.GC) |
| 6 |
System.Math |
2002/3/2 |
算術ライブラリ(System.Math) |
| 7 |
System.Random |
2002/3/2 |
乱数の発生(System.Random) |
| 8 |
System.TimeZone |
2002/3/2 |
タイムゾーンの取得(System.TimeZone) |
| 9 |
OS情報の取得 |
2002/3/2 |
OSのプラットフォーム、バージョン などのの取得(System.Environment.OSVersion) |
| 10 |
例外処理の方法 |
2002/3/2 |
例外処理( try catch finally ) の使い方 |
| 11 |
System.Threading |
2002/3/4 |
スレッドの使い方 |
| 12 |
structとclass どちらを使えばいいの? |
2002/3/4 |
struct は Value Type、class は Reference
Typeなので注意が必要 |
| 13 |
Reference Type と Value Typesについて |
2002/3/4 |
struct のところで解説したように、Reference
Type と Value Type があるので、この違いを正しく理解しておかないと、あれっ?ということになる。 |
| 14 |
Static constructor |
2002/3/4 |
スタティックコンストラクターについて |
| 15 |
Private Constructors |
2002/3/4 |
プライベートコンストラクターについて |
| 16 |
Property の使い方 |
2002/3/4 |
プロパティの使い方 |
| 17 |
NameSpace について |
2002/3/18 |
Fully Qualified Name (FQN 日本語訳は完全修飾名)
でユニークな空間を指定することができる。 |
| 18 |
Stringについて |
2002/3/20 |
文字列操作、フォーマッティング |
| 19 |
Date/Time フォーマットについて |
2002/3/20 |
DateTime のフォーマッティングについて。西暦、和暦の表示など。 |
| 20 |
Operators, chech, unchecked について |
2002/3/22 |
Keyword checked, unchecked とコンパイラーの設定について |
| 21 |
配列について |
2002/3/26 |
配列の宣言、初期化、foreach、paramsの使い方 |
| 22 |
Boxing |
2002/3/26 |
Boxing, ボックス化, Heap, Stack, foreach,
object |
| 23 |
シリアライズ、デシリアライズ |
2002/6/3 |
内容に誤りがあったため、修正が完了するまでリンクをはずします。2003/2/12
BinaryFormatter, Soapormatter, (XmlFormatter) |
| 24 |
デリゲートについて |
2002/7/9 |
デリゲートの解説と使い方、イベントハンドラーとの関係 |
| 25 |
コレクションの使い方 |
2002/7/16 |
ArrayList, Queue, Stack, HashTable などの使い方と注意 |
| 26 |
PRN: ポートへのアクセス |
2002/7/19 |
PRN: ポートへ直接アクセスする Unsafe コードの使い方。 |
| 27 |
C# Design Patterns |
2002/7/28 |
C# のデザインパターン(工事中) |
| 28 |
C# ネーミングガイドライン |
2002/7/29 |
C# の名前付けに関するガイドライン (ネーミングコンベンション) |
| 29 |
ファイルとディレクトリの操作 |
2002/8/5 |
ファイルとディレクトリの操作について |
| 30 |
非同期プログラミング |
2002/8/18 |
デリゲートを使った非同期処理について |
| 31 |
ini ファイルのリード・ライト |
2002/9/14 |
Win32 API を使って、ini ファイルのリード・ライトを行う |
| 32 |
Attributes |
2002/10/14 |
Attributes の使い方について |
| 33 |
WMI の使い方 |
2002/11/25 |
Windows Management Instrumentation の略で、システム管理のためのインターフェースです。 |
| 34 |
Enum の値を列挙 |
2002/12/27 |
Enum の値を列挙する方法について |
| 35 |
Interop |
2003/5/31 |
Interopのメモ |
| 36 |
サーバのリスト |
2003/6/9 |
サーバをリストします。 |
| 37 |
ゴミ箱の中身の削除 |
2003/6/24 |
ゴミ箱の中身を削除する方法 |
| 38 |
Windows バージョン判定 |
2003/10/25 |
Windows のバージョンを判定する方法 |
| 39 |
Domain名、Workgroup名の取得 |
2003/12/7 |
Domain名、Workgroup名の取得する方法 |
2002/3/2 おきまりのHelloWorld!
using System;
namespace HelloWorld
{
/// <summary>
/// HelloWorld
/// </summary>
class HelloWorld
{
static void Main(string[] args)
{
//
Console.WriteLine("Hello World");
for (int i=0; i < args.Length; i++)
{
Console.WriteLine("Argument {0} is {1}", i, args[i]);
}
}
}
}

2002/3/2 DLLを使う
メイン部分
using System;
using MyLibrary;
namespace HelloWorld2
{
/// <summary>
/// HelloWorld2
/// </summary>
class Class1
{
static void Main(string[] args)
{
string str = MyLibrary.HelloWorld.Get();
Console.WriteLine( str );
HelloWorld.Set("HelloWorld2!");
Console.WriteLine( HelloWorld.Get() );
}
}
}
dll 部分 using System;
namespace MyLibrary
{
/// <summary>
/// MyLibrary
/// </summary>
public class HelloWorld
{
// これは悪い例です。
// dllは他のプロセスからも呼ばれるので、Thread Safe なつくりにしておく必要があります。
private static string helloStr ="HelloWorld";
public static string Get()
{
//
//
return helloStr;
}
public static void Set(string str)
{
//
//
helloStr = str;
}
}
}

2002/3/2 環境変数の取得方法(System.DateTime)
using System;
namespace test
{
/// <summary>
/// 日時の取得。
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
Console.WriteLine("System.DateTime.Now = {0}", System.DateTime.Now);
}
}
}
System.DateTime.Now = 2002/03/02 22:02:47
2002/3/2 ガベージコレクションについて(System.GC)
using System;
namespace test
{
/// <summary>
/// Garbage Collectionの確認
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
Console.WriteLine("TotalMemory before Garbage Collection = {0}",
System.GC.GetTotalMemory( false ));
Console.WriteLine("Do Garbage Collection");
System.GC.Collect();
Console.WriteLine("TotalMemory after Garbage Collection = {0}",
System.GC.GetTotalMemory( true ));
}
private void test()
{
string test = "HelloWorld";
}
}
}
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
TotalMemory before Garbage Collection = 14840
Do Garbage Collection
TotalMemory after Garbage Collection = 13304
2002/3/2 算術ライブラリ(System.Math)
using System;
namespace test
{
/// <summary>
/// System.Math
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
Console.WriteLine("System.Math.E = {0}", System.Math.E);
Console.WriteLine("System.Math.PI = {0}", System.Math.PI);
Console.WriteLine("Sin30 = {0}", System.Math.Sin(System.Math.PI /6 ));
}
}
}
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
System.Math.E = 2.71828182845905
System.Math.PI = 3.14159265358979
Sin30 = 0.5
2002/3/2 乱数の発生(System.Random)
using System;
namespace test
{
/// <summary>
/// 乱数の発生
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
Random ran = new System.Random();
Console.WriteLine("Random.Next()");
for( int i = 0; i < 10; i++)
Console.Write("{1} ", i, ran.Next());
Console.WriteLine("\n\nRandom.Next(100)");
for( int i = 0; i < 10; i++)
Console.Write("{1} ", i, ran.Next(100));
Console.WriteLine("\n\nRandom.Next(-10, 10)");
for( int i = 0; i < 10; i++)
Console.Write("{1} ", i, ran.Next(-10, 10));
}
}
}
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
Random.Next()
1960841852 1485561345 1383251404 1457608099
1238100379 1320789039 619096528 1184859963
354121288 1505935124
Random.Next(100)
25 70 4 50 78 31 61 76 46 39
Random.Next(-10, 10)
-7 2 -3 7 -1 -8 -5 -6 -4 1
2002/3/2 タイムゾーンの取得(System.TimeZone)
using System;
namespace test
{
/// <summary>
/// タイムゾーンの取得
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
Console.WriteLine("Los Angels = {0}", System.DateTime.Now);
TimeZone tz = System.TimeZone.CurrentTimeZone;
Console.WriteLine("DaylightName = {0}", tz.DaylightName);
Console.WriteLine("StandardName = {0}", tz.StandardName);
}
}
}
時間を西海岸のサマータイムにセットしてから実行すると、次のようになる。
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
Los Angels = 2002/08/02 7:03:18
DaylightName = 太平洋夏時間
StandardName = 太平洋標準時
2002/3/2 OSのプラットフォーム、バージョン などのの取得(System.Environment.OSVersion)
using System;
namespace test
{
/// <summary>
/// OS情報の取得
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
System.OperatingSystem os = System.Environment.OSVersion;
Console.WriteLine("OS Platform = {0}", os.Platform.ToString());
Console.WriteLine("OS Version = {0}", os.Version.ToString());
}
}
}
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
OS Platform = Win32NT
OS Version = 5.1.2600.0
2002/3/2 例外処理( try catch finally ) の使い方
using System;
namespace test
{
/// <summary>
/// 例外処理
/// </summary>
class Class1
{
static void Main(string[] args)
{
//
DivideByZero();
}
private static void DivideByZero()
{
try
{
int divZero = 0;
int n = 100/divZero;
}
catch (Exception e)
{
Type type = e.GetType();
Console.WriteLine("Exception Type = {0}", type.ToString());
Console.WriteLine("Exception Message = {0}", e.Message);
Console.WriteLine("Exception StackTrace = {0}", e.StackTrace);
}
}
}
}
C:\My Documents\Visual Studio Projects\test1\bin\Release>test1
Exception Type = System.DivideByZeroException
Exception Message = 0 で除算しようとしました。
Exception StackTrace = at test.Class1.divideByZero()
2002/3/4 スレッドの使い方
using System;
using System.Threading;
public class Simple
{
public class MyThread
{
// Threadは sealed classなので、継承できない。
// このため、Threadのdelegateにより呼び出す。
private int number;
public MyThread( int no )
{
number = no;
}
public void Run()
{
while (true)
{
Console.WriteLine("Thread Sleep = {0}", number);
Thread.Sleep(number);
}
}
}
public static void Main()
{
// ThreadからたたかれるMyThreadインスタンスを作る。
MyThread myThread1 = new MyThread(500);
MyThread myThread2 = new MyThread(1000);
// delegate により ThreadStart であるMyThread.Run メソッドを Threadオブジェクトに引き渡す。
// Thread.Start()が呼ばれた時点で、delegateされた MyThread.Runが呼ばれる。
Thread thread1 = new Thread(new ThreadStart(myThread1.Run));
Thread thread2 = new Thread(new ThreadStart(myThread2.Run));
thread1.Start();
thread2.Start();
Thread.Sleep(5000);
thread1.Abort();
thread2.Abort();
thread1.Join();
thread2.Join();
Console.WriteLine();
Console.WriteLine("MyThread.Run has finished");
}
}

2002/3/4
struct と class で Point を作ってみましょう。
// class による Point
class ClassPoint
{
public int x, y;
public string str;
public ClassPoint(int x, int y)
{
this.x = x;
this.y = y;
this.str = "初期文字列";
}
}
// struct による Point
struct StructPoint
{
public int x, y;
public string str;
public StructPoint(int x, int y)
{
this.x = x;
this.y = y;
this.str = "初期文字列";
}
}宣言が違うだけで、同じですね。しかし、 struct は、value type
class は、reference type という本質的な違いがあるので、注意が必要!です。
では、どちらを使えばいいのでしょうか。
特徴をまとめたのが次の表です。
|
struct |
class |
| タイプ |
Value Type |
Reference Type |
| 継承 |
不可 |
可 |
| インターフェース |
可 |
可 |
| メモリーアロケーション |
スタック |
ヒープ |
| 用途 |
簡単な構造のもの |
継承が必要なもの、複雑な構造 |
struct は int などと同じ Value Type (値型)で、スタックにアロケートされます。つまり、ヒープよりアロケートする
class より スタックポインターでアクセスする
struct のほうが高速です。どちらにしてもメモリ上なので事実上それほどの速度差は出ないと思いますが、大量のデータを扱う場合には影響が出てくるはずです。
一般的には、int などと同様にプリミティブなデータ構造には
struct が適しています。
複雑なデータ構造のものに関しては class が適しているといえるでしょう。
継承が必要な場合には、class でしか対応できません。
以下、サンプルコード。
メソッドの引数に渡すとき、struct は、値 が(コピーされ)渡されるのに対し、class
は、リファレンスが渡される。
このため、次のサンプルプログラムのように、class
ではメソッドに渡したリファレンスに対して操作が行われるのに対し、struct
ではコピーした値に対して操作が行われるので、メソッドの中で値を変更しても呼び出し側には反映されない。
using System;
namespace TestStruct
{
/// <summary>
/// structのテスト
/// </summary>
class Class1
{
// class による Point
class ClassPoint
{
public int x, y;
public string str;
public ClassPoint(int x, int y)
{
this.x = x;
this.y = y;
this.str = "初期文字列";
}
}
// struct による Point
struct StructPoint
{
public int x, y;
public string str;
public StructPoint(int x, int y)
{
this.x = x;
this.y = y;
this.str = "初期文字列";
}
}
// struct は value type
// struct StructPoint のパラメータをメソッドの中で変更する。
static private void testStruct (StructPoint sp)
{
sp.x = 99999;
sp.y = 99999;
sp.str = "変更されました。";
}
// class は reference type
// class ClassPoint のパラメータをメソッドの中で変更する。
static private void testClass (ClassPoint cp)
{
cp.x = 99999;
cp.y = 99999;
cp.str = "変更されました。";
}
static void Main(string[] args)
{
ClassPoint cp = new ClassPoint(1, 1);
Console.WriteLine("\nClassPoint = ({0}, {1}, {2}) に初期化されました。", cp.x, cp.y, cp.str);
Console.WriteLine("class ClassPoint のパラメータをメソッドの中で変更します。");
testClass(cp);
Console.WriteLine("結果は ClassPoint = ({0}, {1}, {2})", cp.x, cp.y, cp.str);
StructPoint sp = new StructPoint(1, 1);
Console.WriteLine("\nStructPoint = ({0}, {1}, {2}) に初期化されました。", sp.x, sp.y, sp.str);
Console.WriteLine("struct StructPoint のパラメータをメソッドの中で変更します。");
testStruct(sp);
Console.WriteLine("結果は StructPoint = ({0}, {1}, {2})", sp.x, sp.y, sp.str);
}
}
}

2002/3/4 struct のところで解説したように、Reference
Type と Value Type があるので、この違いを正しく理解しておかないと、あれっ?ということになる。
| Types |
| Reference types |
reference types |
class |
| interface |
| delegate |
| built-in reference types |
object |
| string |
| Value types |
value types |
Struct type |
struct |
| Enumeration type |
enum |
| built-in simple value types |
Numeric types |
Integral types |
| Floating-point types |
| decimal |
| Boolean type |
bool |
| Pointer Type |
これは使わないでしょう。 |
|
|
| Type |
Range |
Size |
| Integral types |
sbyte |
-128 to 127 |
Signed 8-bit integer |
| byte |
0 to 255 |
Unsigned 8-bit integer |
| char |
U+0000 to U+ffff |
Unicode 16-bit character |
| short |
-32,768 to 32,767 |
Signed 16-bit integer |
| ushort |
0 to 65,535 |
Unsigned 16-bit integer |
| int |
-2,147,483,648 to 2,147,483,647 |
Signed 32-bit integer |
| uint |
0 to 4,294,967,295 |
Unsigned 32-bit integer |
| long |
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
Signed 64-bit integer |
| ulong |
0 to 18,446,744,073,709,551,615 |
Unsigned 64-bit integer |
| Floating-point types |
float |
±1.5 × 10-45 to ±3.4 × 1038 (Approximate range) |
Precision 7 digits |
| double |
±5.0 × 10-324 to ±1.7 × 10308 (Approximate range) |
Precision 15-16 digits |
|
2002/3/4 スタティックコンストラクターについて
Static constructorは、access modifiers や
parameters を持たず、クラスが初期化されるときに自動的に呼ばれます。
ユーザは Static constructor を直接呼び出すことはできない。
注意:
通常のコンストラクターと、スタティックコンストラクターを両方宣言することは可能ですが、コンストラクターの起動順序に依存するような書き方をしてしまうと第3者の可読性が下がり、バグの原因になるので避けたほうが良いです。
using System;
class StaticConstructor
{
// Static constructor
static StaticConstructor()
{
Console.WriteLine("StaticConstructorが呼び出されました。");
}
public static void Test()
{
Console.WriteLine("Testメソッドが呼び出されました。");
}
}
class MainClass
{
static void Main()
{
Console.WriteLine("StaticConstructor.Test()を呼び出します。");
// オブジェクトを生成せずに、メソッドを呼び出す。
StaticConstructor.Test();
}
}
StaticConstructor.Test()を呼び出します。
StaticConstructorが呼び出されました。
Testメソッドが呼び出されました。
2002/3/4 プライベートコンストラクターについて
Private Constructorsは、Math class のような、コンストラクターを使わないクラスの初期化や、必ずインスタンスが1つだけを保障するために使えます。
2002/3/4 プロパティの使い方
基本的なプロパティの形は、次のようになる。
read/write, read-only, write-only は、set/getメソッドを実装するかどうかコントロールする。
class Computer
{ public int Speed
{
get
{
return speed;
}
set
{
speed = value;
}
}
}
もう1つ、オーバーライドの方法として、override キーワードを使用する。 // ToString をオーバライドする
public override string ToString()
{
return "Processor Type = " + this.ProcessorType + ", Processor Speed = " + this.Speed;
}このオーバーライドにより、 Console.WriteLine("\nNew Computer {0}",
myComputer);
を実行すると、オーバーライドされた myComputer.ToString()
が呼ばれ、
New Computer Processor Type = Pentium IV,
Processor Speed = 2000
が出力される。
オーバーライドしない場合、 New Computer PropertyTest.Computer
と、オブジェクト名が表示される。
以下、サンプルプログラム using System;
namespace PropertyTest
{
/// <summary>
/// About Computer Class
/// </summary>
class Computer
{
// 初期値の設定
private string processorType ="Celeron";
private int speed = 1000;
// int型の Speed プロパティの宣言
public int Speed
{
get
{
return speed;
}
set
{
speed = value;
}
}
// string型の ProcessorType プロパティの宣言
public string ProcessorType
{
get
{
return processorType;
}
set
{
processorType = value;
}
}
// ToString をオーバライドする
public override string ToString()
{
return "Processor Type = " + this.ProcessorType + ", Processor Speed = " + this.Speed;
}
public static void Main()
{
// Create a new Computer object:
Computer myComputer = new Computer();
Console.WriteLine("Initial Computer {0}", myComputer);
// I bought a new computer
myComputer.ProcessorType = "Pentium IV";
myComputer.speed = 2000;
Console.WriteLine("\nNew Computer {0}", myComputer);
Console.WriteLine("\nNew Processor Type is {0}", myComputer.ProcessorType);
Console.WriteLine("\nNew Computer Speed is {0}", myComputer.Speed );
// こんなこともできる。
Console.WriteLine("myComputer.Speed++ is {0}", myComputer.Speed++ );
// これもOK.
Console.WriteLine("++myComputer.Speed is {0}", ++myComputer.Speed );
// こんなこともできる。
Console.WriteLine("\nNew Processor Type is {0}", myComputer.ProcessorType+=" Hello");
// これもOK.
Console.WriteLine("\nNew Processor Type is {0}", myComputer.ProcessorType+" World!");
}
}
}

2002/3/18 Fully Qualified Name (FQN 日本語訳は完全修飾名)
でユニークな空間を指定することができる。
以下、サンプルプログラムでは、
using Name1
{
TopClass
{
method1;
SecondClass
{
method2;
}
}
using Name2
{
TopClass
{
method1;
SecondClass
{
method2;
}
}
}
}
このような名前空間とスコーピングの時の名前指定に関して検証する。
以下、ソースコード using System;
namespace Name1
{
/// <summary>
/// NameSpace のテストです。
/// </summary>
class TopClass
{
public static string str
{
get
{
return "Name1TopClass";
}
}
public class SecondClass // public でないと Name2からアクセスできない。
{
public static string str
{
get
{
return "Name1SecondClass";
}
}
}
}
namespace Name2
{
class TopClass // Name1 と同じ名前のクラスを宣言する。
{
static string str
{
get
{
return "Name2TopClass";
}
}
public class SecondClass // Name2 と同じ名前のクラスを宣言する。
{
public static string str
{
get
{
return "Name2SecondClass";
}
}
}
static void Main(string[] args)
{
Console.WriteLine("str = {0}", str);
Console.WriteLine("TopClass.str = {0}", TopClass.str);
Console.WriteLine("Name1.TopClass.str = {0}", Name1.TopClass.str);
Console.WriteLine("Name1.TopClass.SecondClass.str = {0}", Name1.TopClass.SecondClass.str);
Console.WriteLine("TopClass.str = {0}", TopClass.str);
Console.WriteLine("Name2.TopClass.str = {0}", Name2.TopClass.str);
Console.WriteLine("Name1.Name2.TopClass.str = {0}", Name1.Name2.TopClass.str);
Console.WriteLine("Name1.Name2.TopClass.SecondClass.str = {0}", Name1.Name2.TopClass.SecondClass.str);
}
}
}
}

Enum の値でどんなものがあるのか、列挙したい場合があります。
以下、サンプルプログラムでは、KnownColor
の値を列挙します。
using System;
using System.Drawing;
namespace EnumEnum
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: アプリケーションを開始するコードをここに追加してください。
//
EnumEnum();
Console.ReadLine();
}
static private void EnumEnum()
{
System.Type knownColorEnumType = Enum.GetUnderlyingType(typeof(System.Drawing.KnownColor));
Console.WriteLine("Enderlying Type = " + knownColorEnumType);
Console.WriteLine("----------------------");
string [] colorNames = Enum.GetNames(typeof(System.Drawing.KnownColor));
foreach(string colorName in colorNames)
{
System.Drawing.KnownColor knownColor =
(KnownColor)Enum.Parse(typeof(System.Drawing.KnownColor), colorName);
Console.WriteLine( colorName );
}
}
}
}
次の図が、実行結果です。

なお、利用例としては、このような使い方があります。

2003/6/24
参照:MSDN
SHEmpyRecycleBin の シェル関数呼び出しを行います。
using System.Runtime.InteropServices;
// flags for SHEmptyRecycleBin
//
enum RecycleFlags :uint
{
// No dialog box confirming the deletion of the objects will be displayed.
SHERB_NOCONFIRMATION = 0x00000001,
// No dialog box indicating the progress will be displayed.
SHERB_NOPROGRESSUI = 0x00000002,
// No sound will be played when the operation is complete.
SHERB_NOSOUND = 0x00000004
}
// Platform SDK 呼び出しプロトタイプ宣言
// HRESULT SHEmptyRecycleBin(
// HWND hwnd,
// LPCTSTR pszRootPath,
// DWORD dwFlags
// );
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
static extern uint SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags);
// Windows.Forms から呼び出す場合
uint result = SHEmptyRecycleBin(this.Handle, null, 0);
// Console から呼び出す場合
uint result = SHEmptyRecycleBin(IntPtr.Zero, null, 0);
RootPath, RecycleFlags は適当にセットしてください。
詳細は、MSDNを参照してください。
|