-
Notifications
You must be signed in to change notification settings - Fork 0
MS_CSharp
2000 年から開発が始まったマイクロソフト
(アンダース・ヘルスバーグ
率いるチーム)が設計・開発したプログラミング言語。
- 構文は C 言語や、C 言語風に構文が設計された C++ や Java などの影響がある。
- 構文以外についてはヘルスバーグが以前の所属である Borland で設計した
Delphi からの影響がある。 - 標準化機構に託して自由な利用を許す(ECMA-334、ISO/IEC 23270:2003、JIS X 3015)など、
姿勢の変化がある。
マルチパラダイム
- 構造化, 命令型、宣言型、手続き型
- イベント駆動型, オブジェクト指向
- ジェネリック
- リフレクション
- 関数型, 並行計算
| 種別 | 内容 |
|---|---|
| マネージ型 |
System.Object クラスから派生する型。ガベージ・コレクタの管理下に置かれる。Equals、GetHashCode、ToString などの基本メソッドを実装する。 |
| アンマネージ型 | 組み込み型 / ポインタ型 / 列挙型 / 構造体(参照型のフィールド・プロパティを含まない) |
移行メモ: 元ページは
System::Object(C++/CLI の記法)となっていたので、
C# の記法System.Objectに改めた。
- 影響を受けた言語 — C++, Delphi, Eiffel, Java, LISP
- 影響を与えた言語 — D言語, F#, Java, Nemerle, Vala
- プラットフォーム — Windows, macOS, Linux など
- ライセンス — Apache ライセンス (Roslyn)
忘れ易いスニペット置き場が欲しかったので。
型推論を利用したローカル変数の宣言。一時的に使用される型を簡単に定義する。
var her = new { Name = "Jane Doe", Age = 20 };
var him = new { Name = "John Doe", Age = 20 };- Dynamic Language Runtime(DLR)追加によりサポートされ、
オブジェクトに対する操作のバインドは実行時まで遅延される。 - Reflection やスクリプト言語との連携が容易になる。
補足:
dynamicはコンパイル時の型検査を放棄するため、
実行時まで誤りが表面化しない。
COM 相互運用や動的な JSON の扱いなど、
他に手段が無い場面に限るのが実務的な指針である。
値型を参照型として扱う。
// ref戻り値をref変数で受け取る
ref int max = ref Max(ref x, ref y);
// limitとmaxは同じ値を参照する
ref int limit = ref max;開発ツールなどが裏で使用していることが多い。
(ユーザー・コーディング部分と、designer 生成部分)
class MyClass { int a; int b; }↓↓↓
partial class MyClass { int a; }
partial class MyClass { int b; }メンバ変数+プロパティ・プロシージャの略記が可能。
private int __value;
public int Value
{
get { return __value; }
private set { __value = value; }
}↓↓↓
public int Value { get; private set; }public int MethodB(int A = 0, int B = 0, int C = 0)
{
return A + B + C;
}上記のオプション引数を選択的に指定できる。
public void MethodA()
{
// 第1引数と第2引数を指定、第3引数は未指定:
Console.WriteLine("Ans: " + MethodB(1, 2)); // Ans: 3 … 1 + 2 + 0
// 第1引数と第3引数を指定、第2引数は未指定:
Console.WriteLine("Ans: " + MethodB(A: 1, C: 3)); // Ans: 4 … 1 + 0 + 3
}補足(オプション引数の注意): 既定値は呼び出し側にコンパイル時に埋め込まれる。
そのため、ライブラリ側で既定値を変えても、
再コンパイルしない利用側には反映されない。
公開 API では、オプション引数よりオーバーロードの方が安全である。
クラスでも使用可能。STL っぽく書く(コンセプトは違うっポイ)。
- where(ジェネリック型制約)
https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/where-generic-type-constraint - C# 7.3 では
System.Enum,System.Delegate,unmanagedの
ジェネリック型制約の種類が追加された。
匿名デリゲートに次ぐ「delegate」の拡張。
// 定義側
public IEnumerable<string> Read(string path, Func<string, string> fx)
{
var result = new List<string>();
using (var reader = new StreamReader(path))
{
while (reader.Peek() >= 0)
{
var line = reader.ReadLine();
result.Add(fx(line));
}
}
return result;
}// 呼出し側
XXXX.Read("hoge.txt", s => s + ".txt");上記のように「Action、Func のデリゲートの型」(ラムダ式って)を使用する。
- 継承せずにインスタンス・メソッドを追加定義。
- 列挙型やインターフェイスにも適用可能。
-
拡張メソッド定義側の名前空間を
インポートしないと発見できないのがアレ
// 定義:第一引数の this に当該インスタンス・メソッドを追加
public static class StringUtil
{
public static string Repeat(this string str, int count)
{
var array = new string[count];
for (var i = 0; i < count; ++i) array[i] = str;
return string.Concat(array);
}
}// 利用:どちらの例も "foofoofoofoo" を返す
StringUtil.Repeat("foo", 4); // 静的メソッドとしての呼び出し
"foo".Repeat(4); // 拡張メソッドとしての呼び出しint[] array1 = new int[] { 1, 3, 5, 7, 9 };
List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Dictionary<string, string> openWith = new Dictionary<string, string>()
{
{"txt", "notepad.exe"},
{"bmp", "paint.exe"},
{"dib", "paint.exe"},
{"rtf", "wordpad.exe"}
};
// 匿名型の配列(型を省略できる。object型には解釈されずコンパイル・エラーになる)
var a = new[] { "foo", "bar", null };// member の初期化
Point p = new Point { X = 0, Y = 1 };
// member の new
var x = new Line
{
A = { X = 1, Y = 2 },
B = { X = 3, Y = 4 },
};
// var (anonymous type)
var anon = new { Name = "Terry", Age = 34 };C# 6 から自動実装プロパティの初期化が可能。
class Class1
{
public string Auth { get; set; } = "BlahBlah";
}System.Type type = typeof(int);.GetType() メソッドと同じ。
int i = 0;
System.Type type = i.GetType();- アンマネージ型のサイズを(バイト単位、
int型で)取得。 - C# 2.0 以降は「組み込み型」に対する
sizeofに関してのみunsafeが不要 -
Marshal.SizeOfメソッドとは違うので注意(こちらはインスタンスのサイズ)。
移行メモ: 元ページの
Marshall.SizeOfは綴りが誤り。
正しくはSystem.Runtime.InteropServices.Marshal.SizeOf(lは 1 つ)。
- 変数や、クラス、メソッド、プロパティなどの名前(識別子)を文字列リテラルとして取得
- 名前空間やクラス名などで修飾されていない名前(必要なら Reflection で取得可能)
移行メモ: 元ページは「変装や、クラス、…」となっていたので
「変数」に正した。
-
is 式
- オブジェクトに指定された型との互換性がある場合、
trueと評価される。 - (拡張)後続に変数を宣言し、
trueと評価された場合、変数にキャストした値を代入する。
- オブジェクトに指定された型との互換性がある場合、
-
as 式
-
互換性のある参照型または null 許容型間で特定の型変換を実行する。
-
非互換の場合は、例外ではなく、
nullを返す。 -
以下の 2 つのコードは等価
expression as type; expression is type ? (type)expression : (type)null;
-
C# では、break; を明記するものの、フォールスルーを禁止されている。
// 定数パターン
switch (変数)
{
case 値1:
いくつかの文1;
break;
case 値2:
いくつかの文2;
break;
default:
いくつかの文;
break;
}// 型パターンと when 句
void Decide(object obj) {
switch (obj) {
case int num when num < 0:
Console.WriteLine($"{num}は負の数です。");
break;
case int num:
Console.WriteLine($"{num}を二乗すると{num * num}です。");
break;
case "B":
Console.WriteLine($"これはBです。");
break;
case string str when str.StartsWith("H"):
Console.WriteLine($"{str}はHから始まる文字列です。");
break;
case string str:
Console.WriteLine($"{str}は文字列です。");
break;
case null:
Console.WriteLine($"nullです");
break;
default:
Console.WriteLine("判別できませんでした");
break;
}
}補足(最新化): C# 8 以降、これは switch 式でより簡潔に書ける。
string Decide(object obj) => obj switch { int num when num < 0 => $"{num}は負の数です。", int num => $"{num}を二乗すると{num * num}です。", string s when s.StartsWith("H") => $"{s}はHから始まる文字列です。", string s => $"{s}は文字列です。", null => "nullです", _ => "判別できませんでした" };switch 式はすべての分岐で値を返すことが強制されるため、
「返し忘れ」がコンパイル時に検出される。
以下の例で、始めに a を評価してその評価値が、真である時は b、
偽である時は c を評価してその評価値を返す。
int x = a ? b : c;- 参考
- 三項演算子?:は悪である。 https://qiita.com/raccy/items/0b25b2f106e2a813828b
- C#の三項演算子をリファクタリングする - PG日誌
https://takachan.hatenablog.com/entry/2018/04/07/124034
// null でない最初の値を返す
object obj1 = null;
object obj2 = new object();
object obj3 = new object();
return obj1 ?? obj2 ?? obj3; // obj2 を返す
// Nullable 型を非 Nullable 型に代入するときに便利
int? i = null;
int j = i ?? -1;補足(現在よく使う関連構文): 本ページ執筆後に追加され、
実務で頻出するもの。
構文 内容 版 ?./?[]null 条件演算子 C# 6 ??=null 合体代入 C# 8 !null 免除演算子(「null でないと分かっている」の明示) C# 8 Nullable 参照型 <Nullable>enable</Nullable>で null 安全性を静的検査C# 8 record値ベースの等価性を持つ参照型 C# 9 is not null否定パターン C# 9 ファイル スコープ名前空間 namespace Foo;C# 10 プライマリ コンストラクタ class Foo(int x)C# 12 コレクション式 int[] a = [1, 2, 3];C# 12 特に Nullable 参照型は、新規プロジェクトのテンプレートで
既定有効になっており、NullReferenceExceptionの削減に効く。
-
C Sharp - Wikipedia
https://ja.wikipedia.org/wiki/C_Sharp -
C# の新機能 | Microsoft Learn
https://learn.microsoft.com/dotnet/csharp/whats-new/
Tags: 移行, .NET開発, プログラミング
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。