„Klasa abstrakcyjna” i „interfejs” są podobnymi pojęciami, a interfejs jest bardziej abstrakcyjny z tych dwóch. Jednym z czynników różnicujących jest to, że klasy abstrakcyjne zapewniają w razie potrzeby implementacje metod dla klas pochodnych. Jednak w języku C # ten czynnik różnicujący został zmniejszony dzięki niedawnemu wprowadzeniu metod rozszerzenia, które umożliwiają implementację metod interfejsu. Innym czynnikiem różnicującym jest to, że klasa może odziedziczyć tylko jedną klasę abstrakcyjną (tj. Nie ma wielokrotnego dziedziczenia), ale może implementować wiele interfejsów. To sprawia, że interfejsy są mniej restrykcyjne i bardziej elastyczne. Więc w C #, kiedy powinniśmy używać klas abstrakcyjnych zamiast interfejsów z metodami rozszerzenia?
Godnym uwagi przykładem modelu interfejsu + metody rozszerzenia jest LINQ, w którym funkcjonalność zapytania jest zapewniona dla każdego typu, który implementuje IEnumerable
za pomocą wielu metod rozszerzenia.