lock
C#にはlockキーワードがありますが、C++/CLIにはありません。
代わりにMonitor::Enter,Monitor::Exitあるいはlockクラスを使います。
詳しくは、方法 : C++ で C# lock キーワードを実装するを参照して下さい。
代わりにMonitor::Enter,Monitor::Exitあるいはlockクラスを使います。
詳しくは、方法 : C++ で C# lock キーワードを実装するを参照して下さい。
オーバーフロー
演算のオーバーフローチェックは面倒ですが、
C#では例外を発生させることができます。
※ ただし、checkedは実行速度が遅くなります。
C++/CLIでは自分でチェックする必要があります。
C#では例外を発生させることができます。
※ ただし、checkedは実行速度が遅くなります。
C++/CLIでは自分でチェックする必要があります。
[C#]
using System;
class Sample
{
uint CheckedPlus1(uint i)
{
return checked(i + 1);
}
uint UncheckedPlus1(uint i)
{
return unchecked(i + 1);
}
static void Main()
{
try
{
Sample sample = new Sample();
Console.WriteLine("0x{0:x} + 1 => 0x{1:x}",
UInt32.MaxValue,
sample.UncheckedPlus1(UInt32.MaxValue));
Console.WriteLine("0x{0:x} + 1 => 0x{1:x}",
UInt32.MaxValue,
sample.CheckedPlus1(UInt32.MaxValue));
}
catch (OverflowException ex)
{
Console.WriteLine(ex.Message);
}
}
}
[出力]
0xffffffff + 1 => 0x0
算術演算の結果オーバーフローが発生しました。
[C++/CLI]
using namespace System;
unsigned int CheckedPlus1(unsigned int i)
{
if (i == UInt32::MaxValue) {
throw gcnew OverflowException();
}
return i + 1;
}
unsigned int UncheckedPlus1(unsigned int i)
{
return i + 1;
}
int main()
{
try
{
Console::WriteLine("0x{0:x} + 1 => 0x{1:x}",
UInt32::MaxValue,
UncheckedPlus1(UInt32::MaxValue));
Console::WriteLine("0x{0:x} + 1 => 0x{1:x}",
UInt32::MaxValue,
CheckedPlus1(UInt32::MaxValue));
}
catch (OverflowException^ ex)
{
Console::WriteLine(ex->Message);
}
return 0;
}
[出力]
0xffffffff + 1 => 0x0
算術演算の結果オーバーフローが発生しました。
自動生成されるコード
C#ではクラスを分割して宣言できます。
C#でWindowsフォームアプリケーションを作成すると、 Form1.csとForm1.Designer.csができ、どちらも partial class Form1と宣言されています。
デザインパネルでボタンを追加するとそのコードがForm1.Designer.csに追加され、 ボタンをダブルクリックするとForm1.csにボタンクリックイベントハンドラができます。
ユーザが編集するコードはForm1.csにでき、 デザインパネルでの操作を反映してコードがForm1.Designer.csにできるので、
ユーザは自動でできるコードをあまり意識せずユーザが行いたい機能のコードに集中することができます。
一方C++/CLIではクラスを分割して宣言できません。
C++/CLIでWindowsフォームアプリケーションを作成すると、 Form1.hができ、自動生成されるコードは次の#pragma region で囲まれています。
#pragma region Windows Form Designer generated code
// 自動生成されるコード
#pragma endregion
デザインパネルでボタンを追加するとそのコードがデザイナ自動生成用のregionに追加され、 ボタンをダブルクリックするとregion外にボタンクリックイベントハンドラができます。
ユーザが編集するコードはregion外、 デザインパネルでの操作を反映するコードはregion内とファイル内で領域が分かれます。
Visual Studioのエディタの機能で#pragma regionで囲まれた領域は左側の+記号をクリックすることで閉じることができます。
閉じていれば、ユーザはユーザのコードに集中できます。
C#でWindowsフォームアプリケーションを作成すると、 Form1.csとForm1.Designer.csができ、どちらも partial class Form1と宣言されています。
デザインパネルでボタンを追加するとそのコードがForm1.Designer.csに追加され、 ボタンをダブルクリックするとForm1.csにボタンクリックイベントハンドラができます。
ユーザが編集するコードはForm1.csにでき、 デザインパネルでの操作を反映してコードがForm1.Designer.csにできるので、
ユーザは自動でできるコードをあまり意識せずユーザが行いたい機能のコードに集中することができます。
一方C++/CLIではクラスを分割して宣言できません。
C++/CLIでWindowsフォームアプリケーションを作成すると、 Form1.hができ、自動生成されるコードは次の#pragma region で囲まれています。
#pragma region Windows Form Designer generated code
// 自動生成されるコード
#pragma endregion
デザインパネルでボタンを追加するとそのコードがデザイナ自動生成用のregionに追加され、 ボタンをダブルクリックするとregion外にボタンクリックイベントハンドラができます。
ユーザが編集するコードはregion外、 デザインパネルでの操作を反映するコードはregion内とファイル内で領域が分かれます。
Visual Studioのエディタの機能で#pragma regionで囲まれた領域は左側の+記号をクリックすることで閉じることができます。
閉じていれば、ユーザはユーザのコードに集中できます。
[C#]
using System;
partial class Part
{
#pragma region 一つ目
void Method1()
{
Console.WriteLine("Method1");
}
#pragma endregion
}
partial class Part
{
#pragma region 二つ目
void Method2()
{
Console.WriteLine("Method2");
}
#pragma endregion
static void Main()
{
Part parts = new Part();
parts.Method1();
parts.Method2();
}
}
[出力]
Method1
Method2
[C++/CLI]
using namespace System;
ref class All
{
public:
#pragma region 一つ目
void Method1() {
Console::WriteLine("Method1()");
}
#pragma endregion
#pragma region 二つ目
void Method2() {
Console::WriteLine("Method2()");
}
#pragma endregion
};
int main()
{
All^ all = gcnew All();
all->Method1();
all->Method2();
return 0;
}
[出力]
Method1()
Method2()
リファクタリング
クラス名、メソッド名、変数名等のシンボル名を変更したいときに
Visual StudioのC#ではシンボル名の所でショートカットメニューの
[リファクター][名前の変更]により関連する名前(メソッド名なら呼び出し箇所等)を一括変更できます。
残念ながらVisual Studio のC++/CLIではサポートされていません。
※ Refactor! for C++ 等をVisual StudioにAddInする方法があります。
ただし、ExpressはサードパーティのAddInがサポートされていません。
残念ながらVisual Studio のC++/CLIではサポートされていません。
※ Refactor! for C++ 等をVisual StudioにAddInする方法があります。
ただし、ExpressはサードパーティのAddInがサポートされていません。
| リファクタリングは長期間開発するプログラムにとって重要な技術です。 次々と機能を追加していくとはじめの設計は成り立たなくなってきます。 そんなときに設計を改善していく技術としてリファクタリングは役に立ちます。 小さなプログラムでもこの考え方は役に立ちます。 はじめに付けた名前はコーディングを進めるに従って意味が変わり名前を変更したくなります。 名前と意味を合わせることで誤解が少なくなります。 |
Flags
enumのFlagsAttributeのときに便利なHasFlagが使えるようになりました。
(.NET Framework4)
(.NET Framework4)
[C#]
using System;
[Flags]
enum Bits
{
Bit1 = 0x1,
Bit2 = 0x2,
Bit3 = 0x4
}
class Program
{
static void Main()
{
var flags = Bits.Bit1;
flags |= Bits.Bit3;
Console.WriteLine(flags);
foreach (Bits flag in Enum.GetValues(typeof(Bits))) {
Console.WriteLine("{0}: HasFlag: {1}", flag, flags.HasFlag(flag));
}
}
}
[出力]
Bit1, Bit3
Bit1: HasFlag: True
Bit2: HasFlag: False
Bit3: HasFlag: True
[C++/CLI]
using namespace System;
[Flags]
enum class Bits
{
Bit1 = 0x1,
Bit2 = 0x2,
Bit3 = 0x4
};
int main()
{
auto flags = Bits::Bit1;
flags = flags | Bits::Bit3;
// flags |= Bits::Bit3; // C++/CLIではエラー
Console::WriteLine(flags);
for each (Bits flag in Enum::GetValues(Bits::typeid)) {
Console::WriteLine("{0}: HasFlag: {1}", flag, flags.HasFlag(flag));
}
return 0;
}
[出力]
Bit1, Bit3
Bit1: HasFlag: True
Bit2: HasFlag: False
Bit3: HasFlag: True
flags |= と使いたくなりますが、C++/CLIではエラーになりました。




