Сколько интерфейсов разрешено использовать? - PullRequest
24 голосов
/ 26 ноября 2010

В C #:

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

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

Есть ли предел для N?

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

Ответы [ 6 ]

41 голосов
/ 26 ноября 2010

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

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

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

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

15 голосов
/ 26 ноября 2010

Количество интерфейсов, которые вы можете реализовать, ограничено возможностями компилятора.Слишком много интерфейсов приводит к исключению стека и потока в компиляторе 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());
8 голосов
/ 26 ноября 2010

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

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

1 голос
/ 26 ноября 2010

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

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

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

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

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

1 голос
/ 26 ноября 2010

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

0 голосов
/ 26 ноября 2010

Есть ограничение

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...