C#8.0からインタフェースに大幅な機能追加が行われました
C#8.0以前のインタフェースはシグネチャだけを集めた純粋仮想関数みたいなものでしたが、C#8.0以降のインタフェースはインスタンスフィールドを持てない抽象クラスのような感じです。
※インタフェースはフィールドを定義できないが多重継承できる
※抽象クラスはフィールドが定義できるが多重継承できない
以下のようなものが定義できるようになりました。
・定数
・演算子
・静的コンストラクタ・静的メソッド・静的プロパティ・静的インデクサ・静的イベント
・インスタンスメソッドの既定の動作
・アクセス修飾子
interface ISample
{
// 定数
const int START_INDEX = 10;
// 静的コンストラクタ
static int _sequence;
// 静的プロパティ
static int Sequence { get => ++_sequence; }
// 静的コンストラクタ
static ISample() => _sequence = START_INDEX;
// インスタンスコンストラクタは不可
//ISample(){}
// インスタンスフィールドもダメ
//private int _field;
// プロパティ
int A { get; set; }
int B { get; set; }
// デフォルト実装
void Output() => Console.WriteLine($"ISample {A + B}");
// public 以外のアクセス指定
protected void Add();
}
public class Sample : ISample
{
// インタフェースを実現したもの
public int A { get; set; }
public int B { get; set; }
void ISample.Add() => Console.WriteLine($"Sample {A + B}");
// デフォルト実装されたものは定義しなくてOK
// クラス側の実装
public void Calc() => Console.WriteLine($"Sample {A + B}");
}
class Program
{
static void Main(string[] args)
{
var s = new Sample { A = 10, B = 20 };
// クラス側の実装はそのまま使える
s.Calc();
// インタフェース側のデフォルト実装はキャストして使う
((ISample)s).Output();
}
}