Сколько интерфейсов разрешено реализовать?

В C#:

сколько интерфейсов класс может реализовать в то же время?

public class MyClass: IInteferface_1, IInterface_2, ... , IInterface_N
{
}

существует ли предел для N?

Не волнуйтесь, я не хочу реализовывать или поддерживать такой объект. Мне просто интересно, есть ли предел.

6 ответов


C# язык не налагает ограничений на количество интерфейсов. Однако есть два практических предела.

во-первых, как указывает chibacity, компилятор в конечном итоге исчерпает пространство кучи или стека при обработке большого количества интерфейсов или чрезвычайно глубоких иерархий интерфейсов.

даже если бы мы исправили эти проблемы, все равно была бы вторая проблема. Реализация интерфейса кодируется в метаданных в таблице InterfaceImpl. Метаданные таблицы обычно могут иметь не более 2^24 членов, поэтому в общей сумме количество интерфейсов, реализованных всеми типами в сборке, должно быть менее 16 миллионов.

очевидно, что вы никогда не столкнетесь с этими ограничениями на практике. Не беспокойся об этом.


количество интерфейсов, которые вы можете реализовать, ограничено тем, что может обрабатывать компилятор. Слишком много интерфейсов приводит к исключению stackoverflow в компиляторе C# (ошибка CS1647). Это привело бы меня к мысли, что нет фиксированного предела, но при определенных условиях компилятор просто бомбит, т. е. число будет зависеть от того, какое пространство стека доступно, когда компилятор обрабатывает класс.

предел, вероятно, будет версией компилятора иждивенец тоже. Следующий код можно использовать для создания тестового набора для зондирования предела.

    int iterations = (int)Math.Pow(2, 8) + 1;

    Func<int, string> getInterfaceName = i => "I" + i;

    StringBuilder sb = new StringBuilder();

    sb.AppendLine("using NUnit.Framework;");
    sb.AppendLine("[TestFixture]");

    sb.AppendLine("public class Test");
    sb.AppendLine("{");

    sb.AppendLine("[Test]");
    sb.AppendLine("public void bling()");
    sb.AppendLine("{");
    sb.AppendLine("Class1 class1 = new Class1();");

    for (int i = 0; i < iterations; i++)
    {
        sb.AppendLine(getInterfaceName(i) + " int" + i + " = class1;");
        sb.AppendLine("int" + i + ".Bling();");
    }

    sb.AppendLine("}");

    for (int i = 0; i < iterations; i++)
    {
        sb.AppendLine("public interface " + getInterfaceName(i) + " { void Bling(); }");
    }

    sb.Append("public class Class1 : " + getInterfaceName(0));

    for (int i = 1; i < iterations; i++)
    {
        sb.Append(", " + getInterfaceName(i));
    }

    sb.Append("{ public void Bling(){} }");

    sb.AppendLine("}");

    File.WriteAllText(@"C:\tmp.cs", sb.ToString());

Если вы задаете этот вопрос с целью реализации большого количества интерфейсов, я бы сказал, что у вас серьезная проблема с дизайном.

насколько я знаю, нет никаких ограничений, кроме памяти вашего компьютера.


рассмотрим, что на самом деле означает для компилятора / времени выполнения сказать MyClass: IInteferface_1, IInterface_2, ... , IInterface_N. Нет ограничения по времени разработки, поскольку компилятор просто гарантирует, что ваш класс имеет соответствующие (метод) подписи для каждого интерфейса, который он должен реализовать. Что касается ограничения времени выполнения, я не думаю, что память имеет большое влияние, поскольку любая ссылка на ваш класс через интерфейс, который он реализует (как проверено во время разработки), просто убедитесь, что ваш класс имеет соответствующую сигнатуру метода для этого интерфейса. Если объект не реализует интерфейс, объекту просто не хватает подписи метода.


Я только что проверил текущую версию спецификации языка Microsoft C 4.0 версии 4.0, и нет никакого упоминания об ограничении в §1.6.4, §1.9, §10.1.4, §10.1.4.2 и §13. Также нет никаких синтаксических ограничений в грамматике в Б. §2.7.

Я, очевидно, не прочитал все 500 страниц, но я не знаю, где еще в этом документе может быть упомянуто ограничение.

Примечание: это относится только к Microsoft C♯, и только к версии 4.0. Я не проверял более ранние версии Microsoft C♯, и я не проверял ECMA / ISO C♯. Кроме того, это относится только к c♯, могут быть ограничения в CLI.

и последнее, но не менее важное: могут быть ограничения для реализации как в Microsoft Visual C♯, так и в Novell Mono C♯, а также ограничения для реализации в реализациях Microsoft и Mono CLI (т. е. CLR и Mono VM).

однако вопрос был о C♯, а не о какой-либо конкретной реализации C♯ и не о CLI, поэтому я чувствую довольно уверенно заявляя, что количество интерфейсов, которые может реализовать класс, неограниченно.


нет лимит

вы ограничены 255, поскольку один байт используется в качестве индексатора JIT в таблице типов для соответствующего интерфейса.