コンテンツにスキップ

C Sharp

出典: フリー百科事典『ウィキペディア(Wikipedia)』
C#
C#
C#のロゴ
パラダイム 構造化プログラミング命令型プログラミングオブジェクト指向プログラミングイベント駆動型プログラミング関数型プログラミングジェネリックプログラミングリフレクションクラスベース、正格プログラミング、マルチパラダイムプログラミング ウィキデータを編集
登場時期 2000年 (24年前) (2000)
設計者 マイクロソフトアンダース・ヘルスバーグ率いるチーム)
開発者 マイクロソフト ウィキデータを編集
最新リリース 12.0/ 2023年11月14日 (6か月前) (2023-11-14)[1]
型付け 強い静的型付け(4.0から動的型導入)
主な処理系 CLR, Mono
影響を受けた言語 C++C言語Java、Delphi、Modula-3EiffelF SharpHaskellIconJ SharpMicrosoft Visual J++Object PascalRustMLVisual Basic ウィキデータを編集
影響を与えた言語 D言語, F#, Java, Nemerle, Vala, TypeScript
プラットフォーム Windows, macOS, Linuxなど
ライセンス Apacheライセンス (Roslyn)
ウェブサイト docs.microsoft.com/ja-jp/dotnet/csharp/ ウィキデータを編集
拡張子 cs、csx ウィキデータを編集
テンプレートを表示

C#C#JavaC++C#Windows.NET Framework2023.NET

ASP.NETWebUnity



 (CLI) .NETVisual J++JavaJava[ 1] (ECMA-334,ISO/IEC 23270:2003,JIS X 3015) 姿



C(C,C++)Delphiasync/awaitTypeScript

[]


Turbo PascalDelphiDelphi

C#

JavaJITC#.NET 

.NETXML WebASP.NET使.NET.NET APIC#.NET2023VB.NET[3]

(Microsoft Visual Studio)Microsoft Visual C#C#Visual Studio CodeC#C# DevKit[4]

CLSCLSF#Visual Basic .NETVisual C++ (C++/CLI) 

バージョンおよびリリース時期[編集]

バージョン 言語仕様 リリース時期 .NET Visual Studio
ECMA[5][6] ISO/IEC マイクロソフト
1.0

ECMA-334:2003 (2002年12月)

ISO/IEC 23270:2003 (2003年4月)

2002年1月 2002年1月 .NET Framework 1.0 .NET (2002)[a 1]
2003年10月 2003年4月 .NET Framework 1.1[b 1] .NET 2003[a 1][b 1]
2.0

ECMA-334:2006 (2006年6月)

ISO/IEC 23270:2006 (2006年9月)

2005年9月 2005年11月
  • .NET Framework 2.0[b 2]
  • .NET Framework 3.0
2005[a 1]
3.0 N/A N/A 2007年8月 2007年11月
2008[a 1]
4.0 N/A N/A 2010年4月 2010年4月 .NET Framework 4[b 3] 2010[a 1]
5.0

ECMA-334:2017 (2017年12月)

ISO/IEC 23270:2018 (2018年12月)

2013年6月 2012年8月 .NET Framework 4.5[b 4]
6.0

ECMA-334:2022 (2022年6月)

N/A Draft 2015年7月
  • .NET Framework 4.6[8]
  • .NET Core 1.0
  • .NET Core 1.1
2015[a 1]
7.0

ECMA-334:2023 (2023年12月)

ISO/IEC 20619:2023 (2023年9月)

N/A 2017年3月 .NET Framework 4.7[9] 2017 version 15.0[a 2]
7.1 N/A N/A N/A 2017年8月 .NET Core 2.0[a 1] 2017 version 15.3[a 3]
7.2 N/A N/A N/A 2017年11月 .NET Core 2.0[a 1] 2017 version 15.5[a 4]
7.3 N/A N/A N/A 2018年5月
  • .NET Core 2.1[b 5]
  • .NET Core 2.2
  • .NET Framework 4.8
2017 version 15.7[a 5]
8.0 N/A N/A N/A 2019年9月
  • .NET Core 3.0[10]
  • .NET Core 3.1
2019 version 16.3[a 6]
9.0 N/A N/A N/A 2020年11月 .NET 5.0[11] 2019 version 16.8[a 7]
10.0[a 8] N/A N/A Proposal 2021年12月
  • .NET 6.0
  • .NET 6.0.1
2022 version 17.0[a 9]
11.0[a 10][b 6] N/A N/A C# feature specifications 2022年11月[a 11][b 6] .NET 7.0[a 11][b 6] 2022 version 17.4[a 11][a 12][b 6]
12.0[a 13][b 7] N/A N/A C# feature specifications 2023年11月[a 14][b 7] .NET 8.0[a 14][b 7] 2022 version 17.8[a 14][a 15]

言語仕様[編集]


CLIC#CLI

C#CLR (CIL) 

C++FORTRANC#CLI

.NET 7.0Native AOTCLICLI[12]

UnityScripting BackendIL2CPP[13]Burst[14] IL2CPPC#CILC++C++BurstC#CILLLVM

Hello World[]


C#Hello World[15]1
Console.WriteLine("Hello World!");

あえて冗長に記載すると下記の様になる。

using System;

namespace Wikipedia
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}



using [16]

namespace("Wikipedia") [17]

class("Program") [17]

(Main) [17]

CC++[]


C#CC++C# .NET JavaC#C#Java

[]


便C#

C#boolwhileifboolCint00便whileif便C#[]

switchstring使case使
C# 7.0  case[b 8]

IEEE 754[a 16]UTF-16[a 17]
C# 9.0 CPU nint/nuint [b 9]

C# 11.0 UTF-8UTF-8[18]

[]


unsafe使unsafeunsafeIntPtr

C#IDisposableusing

[]




C/C++printf()



object (System.Object) objectToString()

 (class)  (struct)  (enum) C/C++



C#C++JITC++



C++Javagetter/setterC# (event) 

C# 2.0C++JavaJava使

C# 2.0[]

[]


 (Partial Type) [a 1]partial
partial class MyClass { int a; }
partial class MyClass { int b; }

これは以下と同義である:

class MyClass { int a; int b; }

これによって、巨大なクラスを分割したり、自動生成されたコードを分離したりすることができる。partial 修飾子はすべての宣言につける必要がある。

[19]

ジェネリクス[編集]

ジェネリクスが導入された[a 1]。これは.NET Framework 2.0の機能である。クラス、構造体、インタフェース、デリゲート、メソッドに対して適用することができる。

.NETのGenericsはC++のテンプレート、あるいはJavaにおけるそれとも異なるもので、コンパイルによってではなく実行時にランタイムによって特殊化される。これによって異なる言語間の運用を可能にし、リフレクションによって型パラメーターに関する情報を取得することができる。また、where節によって型パラメーターに制約を与えることができる。一方、C++のように型パラメーターとしてを指定することはできない。なお、ジェネリックメソッドの呼び出し時に引数によって型パラメーターが推論できる場合、型パラメーターの指定は省略できる。 [20]

静的クラス[編集]


[a 1]static

[19]

[]


#C# 2.0

[21]
yield[]

yield使

[]



[]


Property Accessors get  set[a 1]getpublicsetprivate
public class MyClass
{
  private string status = string.Empty;
  public string Status
  {
    get { return status; }
    private set { status = value; }
  }
}

[22]

Null許容型とnull結合演算子[編集]

nullを保持できる値型、Nullableが導入された[a 1]

int? i = 512;
i = null;

int? j = i + 500; //jはnullとなる。nullとの演算の結果はnullになる。

int?Nullable<int>糖衣構文である。また、nullを保持しているNull許容型のインスタンスをボックス化しようとすると、単に空参照 (null) に変換される[23]

int? x = null;
object o = x;
System.Console.WriteLine(o == null); //Trueが出力される

[24]

また、null結合演算子 (??)が導入された。これは、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をint型に代入することはできない

その他[編集]

C# 3.0からの仕様[編集]

varキーワード[編集]

var キーワードが導入され、型推論を利用したローカル変数の宣言ができるようになった[a 1]

var s = "foo";
// 上の文は右辺が string 型であるため、次のように解釈される:
string s = "foo";
// 以下に挙げる文は誤りである(コンパイルエラーとなる):
var v; // 初期化式を欠いている (型を推論する対象が存在しない)
var v = null; // 型が推論できない (曖昧である)

拡張メソッド[編集]

拡張メソッド (extension method) が導入された[a 1]。既存のクラスを継承して新たなクラスを定義することなく、新たなインスタンスメソッドを疑似的に追加定義することができる。具体的には、入れ子になっていない、非ジェネリックの静的クラス内に、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);
  }
}

この例は、文字列(string 型のインスタンス)を指定した回数繰り返し連結したものを返すメソッド Repeat を、既存の string 型に追加している。このメソッドは、以下のように呼び出すことができる:

// 静的メソッドとしての呼び出し
StringUtil.Repeat("foo", 4);
// 拡張メソッドとしての呼び出し
"foo".Repeat(4);
// (どちらの例も "foofoofoofoo" を返す)

また、列挙型インタフェースなど本来メソッドの実装を持ち得ない型に、見かけ上インスタンスメソッドを追加することも可能である。以下に例を挙げる:

public enum Way
{
  None, Left, Right, Up, Down
}

public static class EnumUtil
{
  public static Way Reverse(this Way src)
  {
    switch (src)
    {
      case Way.Left:  return Way.Right;
      case Way.Right: return Way.Left;
      case Way.Up:    return Way.Down;
      case Way.Down:  return Way.Up;
      default: return Way.None;
    }
  }
}

このメソッドは以下のように呼び出すことができる:

Way l = Way.Left;
Way r = l.Reverse(); // Way.Right

[a 18]

[]


[a 1]partial  private  void  partial :
partial class Class
{
  partial void DebugOutput(string message);
  
  void Method()
  {
    DebugOutput("Some message");
    Console.WriteLine("Did something.");
  }
}

上のコードにおいて Method() を呼び出すと、Did something. と表示されるだけだが、ここで以下のコード:

partial class Class
{
  partial void DebugOutput(string message)
  {
    Console.Write("[DEBUG: {0}] ", message);
  }
}

を追加した上で Method() を呼び出すと、[DEBUG: Some message] Did something. と表示される。

ラムダ式[編集]

ラムダ式が導入された[a 1]。この名前はラムダ計算に由来する。

以下の匿名メソッド

// iを変数としてi+1を返すメソッド
delegate (int i) { return i + 1; }

は、ラムダ式を使って次のように記述できる:

(int i) => i + 1; /* 式形式のラムダ */
//或いは:
(int i) => { return i + 1; }; /* ステートメント形式のラムダ */

Expression<TDelegate>CILCILDOMLINQSQL

3:
public static string ToRPN(Expression<Func<int, int, int, int>> expression)
{
  return Parse((BinaryExpression) expression.Body).TrimEnd(' ');
}

private static string Parse(BinaryExpression expr)
{
  string str = "";
  
  if (expr.Left is BinaryExpression)
  {
    str += Parse((BinaryExpression) expr.Left);
  }
  else if (expr.Left is ParameterExpression)
  {
    str += ((ParameterExpression) expr.Left).Name + " ";
  }
  else if (expr.Left is ConstantExpression)
  {
    str += ((ConstantExpression) expr.Left).Value + " ";
  }

  if (expr.Right is BinaryExpression)
  {
    str += Parse((BinaryExpression) expr.Right);
  }
  else if (expr.Right is ParameterExpression)
  {
    str += ((ParameterExpression) expr.Right).Name + " ";
  }
  else if (expr.Right is ConstantExpression)
  {
    str += ((ConstantExpression) expr.Right).Value + " ";
  }
  
  return str + expr.NodeType.ToString()
    .Replace("Add", "+")
    .Replace("Subtract", "-")
    .Replace("Multiply", "*")
    .Replace("Divide", "/")
    + " ";
}

// 呼び出し例:
ToRPN((x, y, z) => (x + 1) * ((y - 2) / z)); // "x 1 + y 2 - z / *" を返す

オブジェクト初期化の簡略化[編集]

オブジェクトの初期化が式として簡潔に記述できるようになった。

var p = new Point { X = 640, Y = 480 };
// 上の文は次のように解釈される:
Point __p = new Point();
__p.X = 640;
__p.Y = 480;
Point p = __p;

また、コレクションの初期化も同様に簡潔に記述できるようになった。

var l = new List<int> {1, 2, 3};
var d = new Dictionary<string, int> {{"a", 1}, {"b", 2}, {"c", 3}};
// 上の文は次のように解釈される:
List<int> __l = new List<int>();
__l.Add(1);
__l.Add(2);
__l.Add(3);
List<int> l = __l;
Dictionary<string, int> __d = new Dictionary<string, int>();
__d.Add("a", 1);
__d.Add("b", 2);
__d.Add("c", 3);
Dictionary<string, int> d = __d;

便 __p__l__d 

[]


[a 1] get; set; C# 5.0  get;set;C# 6.0  get; :
public int Value { get; set; }

は、以下のようなコードに相当する動作をする:

private int __value;
public int Value
{
  get { return __value; }
  set { __value = value; }
}

但し、上のコードでは匿名のフィールドに便宜的に __value と命名している。実際はプログラマはこのフィールドにアクセスすることはできない。

匿名型[編集]

一時的に使用される型を簡単に定義するための匿名型が導入された[a 1]。以下に例を挙げる:

new { Name = "John Doe", Age = 20 }

上の式は、以下の内容のクラスを暗黙に定義する。定義されたクラスは匿名であるが故にプログラマは参照できない。

public string Name { get; }
public int Age { get; }

同じ型、同じ名前のプロパティを同じ順序で並べた匿名型は同じであることが保証されている。即ち、以下のコード:

var her = new { Name = "Jane Doe", Age = 20 }
var him = new { Name = "John Doe", Age = 20 }

において、her.GetType() == him.GetType()true である。

配列宣言の型省略[編集]

new キーワードを用いた配列の宣言の際、型を省略できるようになった。匿名型の配列を宣言する際に威力を発揮する。

var a = new[] {"foo", "bar", null};
// 上の文は次のように解釈される:
string[] a = new string[] {"foo", "bar", null};
// 以下の文:
var a = new[] {"foo", "bar", 123};
// は次のように解釈されることなく、誤りとなる:
object[] a = new object[] {"foo", "bar", 123};

クエリ式[編集]

LINQ をサポートするために、クエリ式が導入された[a 1]。これは SQL の構文に類似しており、最終的に通常のメソッド呼び出しに変換されるものである。以下に例を示す:

var passedStudents =
  from s in students
  where s.MathScore + s.MusicScore + s.EnglishScore > 200
  select s.Name;

上のコードは以下のように変換される:

var passedStudents = students
  .Where(s => s.MathScore + s.MusicScore + s.EnglishScore > 200)
  .Select(s => s.Name);

C# 3.0で追加された構文の多くは式であるため、より巨大な式(当然クエリ式も含まれる)の一部として組み込むことができる。旧来複数の文に分けたり、作業用の変数を用意して記述していたコードを単独の式としてより簡潔に記述できる可能性がある。

出井秀行著の『実戦で役立つ C#プログラミングのイディオム/定石&パターン』(技術評論社、2017年)という書籍ではクエリ構文よりメソッド構文を推奨しており、クエリ構文ではLINQの全ての機能を使用できるわけではないこと、メソッド呼び出しは処理を連続して読める可読性があること、メソッド呼び出しであればMicrosoft Visual Studioの強力なインテリセンスが利用できることを理由に、著者はクエリ構文をほとんど使用していないと記している。

C# 4.0からの仕様[編集]

dynamicキーワード[編集]

dynamicキーワードが導入され、動的型付け変数を定義できるようになった[a 1]。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。

// xはint型と推論される:
var x = 1; 
// yはdynamic型として扱われる:
dynamic y = 2; 

public dynamic GetValue(dynamic obj)
{
  // objにValueが定義されていなくとも、コンパイルエラーとはならない:
  return obj.Value;
}

オプション引数・名前付き引数[編集]

VBC++に実装されているオプション引数・名前付き引数が、C#でも利用できるようになった[a 1]

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となっている
}

// 引数が指定されなかった場合のデフォルト値を等号で結ぶ:
public int MethodB(int A = 0, int B = 0, int C = 0)
{
  return A + B + C;
}

ジェネリクスの共変性・反変性[編集]

ジェネリクスの型引数に対してin、out修飾子を指定することにより、ジェネリクスの共変性・反変性を指定できるようになった[a 1]

IEnumerable<string> x = new List<string> { "a", "b", "c" };
// IEnumerable<T>インターフェイスは型引数にout修飾子が指定されているため、共変である。
// したがって、C# 4.0では次の行はコンパイルエラーにならない
IEnumerable<object> y = x;

C# 5.0からの仕様[編集]

C# 6.0からの仕様[編集]

  • 自動実装プロパティの初期化子[a 19]
  • get のみの自動実装プロパティおよびコンストラクタ代入[a 19]
  • 静的 using ディレクティブ[a 19]
  • インデックス初期化子[a 19]
  • catch/finally での await[a 19]
  • 例外フィルタ[a 19]
  • 式形式のメンバー (expression-bodied members)[a 19]
  • null条件演算子[a 19]
  • 文字列補間(テンプレート文字列)[a 19]
  • nameof 演算子[a 19]
  • #pragma
  • コレクションの初期化子での拡張メソッド[a 19]
  • オーバーロード解決の改善[a 19]

静的 using ディレクティブ[編集]

静的 using ディレクティブを利用することで、型名の指定無しに他クラスの静的メンバーの呼び出しを行えるようになった。利用するにはusing staticの後に完全修飾なクラス名を指定する。

using static System.Math;
// ↑ソースコードの上部で宣言
class Hogehoge {
    // System.Math.Pow() , System.Math.PI を修飾無しで呼び出す
    double area = Pow(radius, 2) * PI;
}

例外フィルタ[編集]

catchの後にwhenキーワードを使用することで、処理する例外を限定することができるようになった。

try {
    // ...
}
catch (AggregateException ex) when (ex.InnerException is ArgumentException) {
    // ...
}

C# 7.0からの仕様[編集]

  • 出力変数宣言
  • パターンマッチング (is 式/switch 文)
  • タプル (タプル記法/分解/値の破棄)
  • ローカル関数
  • 数値リテラルの改善(桁セパレータ/バイナリリテラル)
  • ref戻り値、ref変数
  • 非同期戻り値型の汎用化
  • Expression-bodied 機能の拡充(コンストラクタ/デストラクタ/get/set/add/remove)
  • Throw 式

出力変数宣言[編集]

out引数で値を受け取る場合、その場所で変数宣言可能となった[a 20]

total += int.TryParse("123", out var num) ? num : 0;

パターンマッチング[編集]

is 式の拡張[編集]

is式の構文が拡張され、型の後ろに変数名を宣言できるようになった[a 20]。 拡張されたis式はマッチした場合に宣言した変数にキャストした値を代入し、さらにtrueと評価される。 マッチしなかった場合はfalseと評価され、宣言した変数は未初期化状態となる。

void CheckAndSquare(object obj) {
    // objの型チェックと同時にnumに値を代入する。
    if (obj is int num && num >= 0) {
        num = num * num;
    }
    else {
        num = 0;
    }
    // if文の条件セクションは、ifの外側と同じスコープ
    Console.WriteLine(num);
}
switch 文の拡張[編集]

switchcase casewhen switchcase[a 21]
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;
    }
}

タプル[編集]

タプルのための軽量な構文が導入された[a 20]。従来のSystem.Tupleクラスとは別に、System.ValueTuple構造体が新しく追加された。

タプル記法[編集]

2個以上の要素を持つタプルのための記法が導入された。 引数リストと同様の形式で、タプルを記述できる。

// タプル記法
(int, string) tuple = (123, "Apple");
Console.WriteLine($"{tuple.Item1}個の{tuple.Item2}");
分解[編集]

多値戻り値を簡単に扱えるように、分解がサポートされた[a 20]

var tuple = (123, "Apple");
// 分解
(int quantity, string name) = tuple;
Console.WriteLine($"{quantity}個の{name}");

分解はタプルに限らない。Deconstruct()メソッドが定義されたクラスでも、分解を利用できる[a 20]

以下に、DateTime型に分解を導入する例を示す。

static class DateExt {
    public static void Deconstruct(this DateTime dateTime, out int year, out int month, out int day) {
        year = dateTime.Year;
        month = dateTime.Month;
        day = dateTime.Day;
    }
}

上記のコードでDateTime型にDeconstruct()拡張メソッドを定義し、

// 分解
(int year, int month, int day) = DateTime.Now;

のように左辺で3つの変数に値を受け取ることができる。

値の破棄[編集]

分解、out引数、パターンマッチングで、値の破棄を明示するために_が利用できるようになった。 破棄された値は、後で参照することはできない。

// 年と日は使わない
(_, int month, _) = DateTime.Now;

// 解析結果だけ取得し、変換された値は使わない
bool isNumeric = int.TryParse(str, out _);

switch (obj) {
    // string型で分岐するが、値は使わない
    case string _:
        // Do something.
        break;
}

ref戻り値、ref変数[編集]

refキーワードの使用方法が拡張された。これによって、安全な参照の使い道が広がった。

ref戻り値[編集]

戻り値の型をrefで修飾することで、オブジェクトの参照を戻り値とすることができる。

// 二つの参照引数の内、値の大きいものの参照戻り値を返す
static ref int Max(ref int left, ref int right) {
    if (left >= right) {
        return ref left;
    }
    else {
        return ref right;
    }
}

変数の寿命は変わらないため、メソッド終了時に破棄されるローカル変数をref戻り値とすることはできない。

static int s_count = 1;

// メンバーの参照はref戻り値になる。
static ref int ReturnMember() {
    return ref s_count;
}
// ref引数はもちろんref戻り値になる。
static ref int ReturnRefParam(ref int something) {
    return ref something;
}
// ローカル変数をref戻り値とすることはできない。
// static ref int ReturnLocal() {
//     int x = 1;
//     return ref x;
// }
ref変数[編集]

ローカル変数の型をrefで修飾することで、参照を代入することができる。

// 参照戻り値を参照変数で受け取る
ref int max = ref Max(ref x, ref y);
// limitとmaxは同じ値を参照する
ref int limit = ref max;

C# 7.1からの仕様[編集]

非同期なMainメソッド[編集]

Mainメソッドの戻り値として、Task型、Task(int)型が認められた[a 22]

static Task Main()
static Task<int> Main()

default式[編集]

型推論可能な場面では、defaultの型指定は省略可能となった[a 22]

int number = default;
string name = default;

C# 7.2からの仕様[編集]


C#7.2[a 23][28]

[]



inref readonly[]

in ref readonly


readonly[]

readonly readonlyreadonlythis


ref[]

ref refbox

Span<T>unsafestackalloc

[]


C#4.0
Hogehoge(name: "John", 17);

private protected アクセス修飾子[編集]

同一アセンブリ内、かつ、継承先からのアクセス許可を表すprivate protectedアクセス修飾子が追加された。

数値リテラルの改善[編集]

十六進リテラルの0x、二進リテラルの0bの直後のアンダースコアが認められた。

int bin = 0b_01_01;
int hex = 0x_AB_CD;

C# 7.3からの仕様[編集]

C#7.3では以下の仕様が追加された[a 24]

  • ジェネリック型制約の種類の追加
    • System.Enum, System.Delegate
    • unmanaged (文脈キーワード)
unsafe class MyGenericsClass<T1,T2,T3> 
    where T1 : System.Enum
    where T2 : System.Delegate
    where T3 : unmanaged {

    public MyGenericsClass(T1 enum1, T1 enum2, T2 func, T3 unmanagedValue) {
        if (enum1.HasFlag(enum2)) {
            func.DynamicInvoke();
        }
        else {
            T3* ptr = &unmanagedValue;
        }
    }
}
  • refローカル変数の再割り当て
  • stackalloc初期化子
  • Indexing movable fixed buffers
  • カスタムfixedステートメント
  • オーバーロード解決ルールの改善
  • 出力変数宣言の利用箇所の追加
class MyOutVar {
    // メンバー変数初期化子やコンストラクタ初期化子で出力変数宣言が可能
    readonly int x = int.TryParse("123", out var number) ? number : -1;
}
  • タプル同士の比較
(long, long) tuple = (1L, 2L);
// タプルのすべての要素間で == が比較可能
if (tuple == (1, 2)) { }
// 要素数が異なるタプル同士は比較できない。
//if (tuple == (1, 2, 3)) { }
  • バッキングフィールドに対するAttribute指定
// C#7.2までは無効な指定(コンパイル自体は可能。無視される)
// C#7.3からはバッキングフィールドに対するAttribute指定と見なされる
[field: NonSerialized]
public int MyProperty { get; set; }

C# 8.0からの仕様[編集]


C# 8.0[a 25][29]

null[]


null?null

?null

nullnullNullable<T>
null[]

nullnull C#7.3

Nullable  null

#nullable  null
annotations warnings
null[]

null !使

[]






 public 

 virtual  override

overridesealed

[]


switch

switch







[]


IAsyncEnumerable<T>
async IAsyncEnumerable<int> EnumerateAsync() {
    await Task.Delay(100);
    yield return 1;
    await Task.Delay(100);
    yield return 2;
}

await foreachによって非同期ストリームを列挙する。

async void SpendAsync() {
    await foreach (var item in EnumerateAsync()) {
        Console.WriteLine(item);
    }
}

範囲指定[編集]

IndexRangeを指定できる専用構文が追加された。

  Index a = 1; // new Index(1, fromEnd: false)
  Index b = ^1; // new Index(1, fromEnd: true)
  Range range = a..b; // new Range(start: a, end: b)

その他の仕様[編集]

  • 静的ローカル関数
  • null結合代入演算子
  • 構造体の読み取り専用メンバー
  • using 宣言
  • ref構造体のDispose
  • ジェネリクスを含むアンマネージ型
  • 式中のstackalloc
  • 文字列補間のトークン順序の緩和

C# 9.0からの仕様[編集]

C# 9.0で追加された仕様は以下の通り。

[a 26]

  • レコード
  • プロパティのinitアクセサ
  • 最上位レベルステートメント
  • パターンマッチングの拡張
  • new式の型推論
  • 条件演算子の型推論
  • 共変戻り値
  • GetEnumeratorの拡張メソッド対応
  • 静的匿名関数
  • ラムダ式引数の破棄
  • ローカル関数への属性適用
  • パフォーマンスと相互運用
    • ネイティブサイズの整数型(nint nuint型)
    • 関数ポインタ(delegate*型)
    • 変数初期化フラグの抑制
  • コードジェネレータのサポート
    • モジュール初期化子
    • 部分メソッドの拡張

C# 10.0からの仕様[編集]

C# 10.0で追加された仕様は以下の通り。

[a 27]

  • レコード構造体
  • 構造体型の機能強化
  • 補間された文字列ハンドラー
  • global using ディレクティブ
  • ファイル スコープの名前空間の宣言
  • 拡張プロパティのパターン
  • ラムダ式の機能強化
  • const 補間文字列を許可する
  • レコードの型で ToString() を封印できる
  • 限定代入の機能強化
  • 同じ分解で代入と宣言の両方を許可する
  • メソッドで AsyncMethodBuilder 属性を許可する
  • CallerArgumentExpression 属性
  • 拡張 #line pragma
  • 警告ウェーブ 6

C# 11.0からの仕様[編集]

C# 11.0で追加された仕様は以下の通り。[a 10][b 6]

生文字列リテラル[編集]

エスケープなどの加工を施さない文字列を3個の二重引用符で括って表現できる様になった。未加工の文字リテラルとも呼ばれる。

string logMsg = """
	原因不明のエラが発生しました。
	詳細はログファイル "C:\Logs\exception.log" を確認してください。
	""";

汎用属性[編集]

属性の型が型引数を持てる様になった。

// 属性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ConverterContractAttribute<TFrom, TTo> : Attribute { }

// 使用例
[ConverterContract<byte, string>()]
[ConverterContract<sbyte, string>()]
[ConverterContract<short, string>()]
[ConverterContract<ushort, string>()]
[ConverterContract<int, string>()]
[ConverterContract<uint, string>()]
[ConverterContract<long, string>()]
[ConverterContract<ulong, string>()]
public class IntToStringConverter
{
	// ...
}

パターンマッチングの拡張[編集]

リストや配列に対するパターンマッチが可能になった[a 28][b 10]

int[] nums = new[] { 0, 1, 2, 3, 4, 5 };
if (nums is [ 0, 1, 2, .. ]) {
	Console.WriteLine("配列は 0, 1, 2 から始まります。");
} else {
	Console.WriteLine("配列は 0, 1, 2 から始まりません。");
}

また、Span<char>ReadOnlySpan<char>に対して文字列を用いたパターンマッチが可能になった。

bool CheckSignature(ReadOnlySpan<char> sig)
{
	return sig is "HOGE";
}

ジェネリック型数値演算[編集]


[a 29][b 11]

>>>

int

checked

static abstractstatic virtual[a 30][a 31]

[a 32]
// 大抵の演算子インターフェイスは System.Numerics 内に実装されている。
using System.Numerics;

// 任意の型に対して加算を行う事ができる関数。
static T MyAdd<T>(T value1, T value2)
	where T: IAdditionOperators<T, T, T> // 加算が可能な型のみを受け付ける制約。
	=> value1 + value2; // + 演算子を使う事ができる。

// 上記の関数定義のみで、下記の様に加算演算が定義された型であれば、任意の型で呼び出す事ができる。
int    a = MyAdd(  123,   456); // 結果:579
ulong  b = MyAdd(111UL, 222UL); // 結果:333
double c = MyAdd( 1.5D,  2.1D); // 結果:3.6

その他の仕様[編集]

  • UTF-8 文字列リテラル
  • 文字列補間式の改行
  • ファイルローカル型
  • 必須メンバー
  • auto-default 構造体(構造体の未初期化のフィールド変数が自動的に既定値に初期化される)
  • nameof のスコープ拡張
  • IntPtr に別名 nintUIntPtr に別名 nuint が付いた
  • ref フィールド
  • scoped ref 変数
  • メソッドグループからデリゲートへの変換の改善
  • 警告ウェーブ 7

C# 12.0からの仕様[編集]

C# 12.0で追加された仕様は以下の通り。[a 13][b 7]

クラスと構造体のプライマリコンストラクター[編集]

レコード型(record)以外のクラス(class)と構造体(struct)でプライマリコンストラクターが使えるようになった。

class Example(string message) 
{
    public string Message { get; } = message;
}

コレクション式[編集]

配列、コレクション、Span<T>などの初期化の記法が共通の記法([])で書けるようになった。

// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];

スプレッド演算子[編集]

コレクション式で複数のコレクションをインライン展開できる新しい演算子(..)が追加された。

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
int[] single = [.. row0, .. row1, .. row2];

[]




 



ref readonly 




[]


C#Ecma International[2][30] C#5


Visual Studio 2015 使.NET (Roslyn)ApacheGitHub[31]WindowsmacOSLinuxC#C#VB.NETVB.NETIDEAPI

Visual Studio 2013 使Visual C# 

2006C# 2.0Shared Source Common Language Infrastructure (CLI) C#

Mono ProjectMono Mono Compiler Suite (mcs)

2012DotGNU ProjectPortable.NET the C-Sharp code compiler (cscc)

[]


ECMA-334 3rd/4th/5th edition C# C SharpLATIN CAPITAL LETTER C (U+0043)  NUMBER SIGN # (U+0023) [32]  (, MUSIC SHARP SIGN (U+266F))  (#) ASCII

"#".NET使J#JavaA#AdaF#System F[33]"#"Gtk#GTKGNOME.NETCocoa#Cocoa (API)使SharpDevelop"Sharp"

C#A-GC[]C++C1

C#C++++C++[34][35]

[]

  1. ^ 全てではなく一部にプロプライエタリなコンポーネントもある。そのため、それに依存するものなど、後述のMonoなどで制限がある場合がある[2]
  2. ^ a b (LINQを除く)[7]

出典[編集]



(一)^ Announcing C# 12.   (20231114). 20231219

(二)^ abAbel Avram (2009729). C#CLI. InfoQ. 2019122

(三)^ Visual Basic  - Visual Basic.  Microsoft (2023510). 20231223

(四)^ Visual Studio Code  C#  - Visual Studio Subscription.  Microsoft (20231013). 20231223

(五)^ Standard ECMA-334.  ECMA. 20231223

(六)^ Standard ECMA-334-archive. 2018111320181113

(七)^ Using C# 3.0 from .NET 2.0.  Danielmoth.com (2007513). 2012104

(八)^ Microsoft.NET Framework 4.6. . https://forest.watch.impress.co.jp/docs/news/712658.html 2021123 

(九)^ .NET Framework 4.7. InfoQ. https://www.infoq.com/jp/news/2017/05/net47-released/ 2021123 

(十)^ Micorsoft.NET Core 3.0. InfoQ. https://www.infoq.com/jp/news/2019/12/microsoft-releases-dotnet-core-3/ 2021123 

(11)^ Richard Lander (20201110). Announcing .NET 5.0 (). .NET Blog.  Microsoft. 20201111

(12)^ Native AOT deployment overview - .NET.  Microsoft (2023912). 20231223

(13)^ IL2CPP  - Unity .  Unity. 20231223

(14)^ Burst .  Unity. 20231223

(15)^ Hello World - C# .  Microsofit. 20231223

(16)^  using  .NET  SDK . 20231223

(17)^ abc - C#  - C#. 20231223

(18)^  - C#  - C#.  Microsoft (2023510). 20231223

(19)^ ab 2005, p. 70.

(20)^  2005, pp. 6364.

(21)^  2005, pp. 6870.

(22)^  2005, pp. 70, 71.

(23)^ null  (C#  ) (pdf).  Microsoft. 200862

(24)^  2005, p. 68.

(25)^  2005, pp. 66, 67.

(26)^  2005, p. 71.

(27)^  2005, p. 72.

(28)^ Mads Torgersen (20171115). Welcome to C# 7.2 and Span (). .NET Blog.  Microsoft. 20171123

(29)^ MicrosoftC# 8.0. InfoQ (20191210). 20191212

(30)^ Tim Smith (2010104). Java.NET. InfoQ. 2019122

(31)^ dotnet/roslyn - GitHub

(32)^ Standard ECMA-334 C# Language Specification

(33)^ The A-Z of programming languages: F# | Network World

(34)^  with Anders Hejlsberg in Microsoft Developers Conference 2006

(35)^ C#

公式発表[編集]



(一)^ abcdefghijklmnopqrstuvwxyzaaC# . Microsoft Docs. 20191212

(二)^ Visual Studio 2017  15.0  . Microsoft Docs. 2021123

(三)^ Visual Studio 2017 15.3 Release Notes. Microsoft Docs. 20181112

(四)^ Visual Studio 2017 15.5 Release Notes. Microsoft Docs. 20181112

(五)^ Visual Studio 2017 15.7 Release Notes. Microsoft Docs. 2018824

(六)^ Visual Studio 2019 Release Notes. Microsoft Docs. 2019930

(七)^ Visual Studio 2019 Release Notes. Microsoft Docs. 20201110

(八)^ What's new in C# 10 (). docs.microsoft.com. 2022628

(九)^ Visual Studio 2022 version 17.0 Release Notes. docs.microsoft.com. 2022628

(十)^ abC# 11 . Microsoft Learn. 2023815

(11)^ abc.NET 7 is Available Today (). .NET Blog. 2023815

(12)^ Visual Studio 2022  17.4  . Microsoft Learn. 2023815

(13)^ abC# 12 . Microsoft Learn. 20231219

(14)^ abcAnnouncing .NET 8 (). .NET Blog. 20231219

(15)^ Visual Studio 2022  17.8  . Microsoft Learn. 20231219

(16)^ 2-2 . Microsoft Docs. 20181111

(17)^ .NET . Microsoft Docs. 20181111

(18)^  (C#  ). Microsoft Docs. 20181110

(19)^ abcdefghijklC# 6 . Microsoft Docs. 20191212

(20)^ abcdeC# 7.0 . Microsoft Docs. 20191212

(21)^ switch (C# ). Microsoft Docs. 2017910

(22)^ abC# 7.1 . Microsoft Docs. 20191212

(23)^ C# 7.2 . Microsoft Docs. 20191212

(24)^ C# 7.3 . Microsoft Docs. 20191212

(25)^ C# 8.0 . Microsoft Docs. 20191212

(26)^ What's new in C# 9.0. Microsoft Docs. 20211017

(27)^ What's new in C# 10.0. Microsoft Docs. 2022113

(28)^  . Microsoft Learn. 2023815

(29)^ . Microsoft Learn. 2024530

(30)^ . Microsoft Learn. 2024530

(31)^ : C# 11 調 - . Microsoft Learn. 2024530

(32)^ IAdditionOperators<TSelf,TOther,TResult> . Microsoft Learn. 2024530

個人サイト[編集]



(一)^ abcdC# 1.0 - C# . 2021123

(二)^ C# 2.0  - C# . 2021123

(三)^ C# 4.0  - C# . 2021123

(四)^ C# 5.0  - C# . 2021123

(五)^ C# 7.3  - C# . 2021123

(六)^ abcdeC# 11.0  - C# . ++C++; // C. 2023815

(七)^ abcdC# 12.0  - C# . ++C++; // C. 20231219

(八)^   - C# . 20231223

(九)^ C# 9.0  - C#  (202059). 20231223

(十)^  . ++C++; // C. 2023815

(11)^ Generic Math C# 11 . ++C++; // C. 2024530

[]


 C# 2.0C MAGAZINE20052172  

C#5︿2022721ISBN 978-4-7981-7556-0 

[]



C#

C#

 (C#)


.NET (.NET Core)

.NET Framework

Mono

Xamarin


Visual Studio
Visual C#

Visual Studio Code

JetBrains Rider - .NET

MonoDevelop - OSS
Xamarin Studio

Visual Studio for Mac

SharpDevelop - 


C#Java

[]


C#  -  | Microsoft Docs - 


Introduction - C# language specification | Microsoft Learn - C# Microsoft Docs

ECMA-334 - Ecma International ECMA-334 C# 

JIS X 3015:2008C#調

C# Compiler | Mono Mono C#