web-dev-qa-db-ja.com

いくつのインターフェースを実装できますか?

C#の場合:

クラスが実装できるインターフェイスの数同時に

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

Nに制限はありますか?

そのようなオブジェクトを実装または保守したくないので心配しないでください。限界があるのか​​と思っていました。

24
Liviu M.

C#languageは、インターフェイスの数に制限を課しません。ただし、実際には2つの制限があります。

まず、chibacityが指摘しているように、コンパイラは、多数のインターフェイス、またはインターフェイスの非常に深い階層を処理するときに、最終的にヒープまたはスタックスペースを使い果たします。

これらの問題を修正したとしても、2番目の問題があります。インターフェイスの実装は、InterfaceImplテーブルのメタデータにエンコードされます。メタデータテーブルは通常2 ^ 24を超えるメンバーを持つことができないため、アセンブリ内のすべてのタイプによって実装されるインターフェイスのtotal数は約16未満である必要があります百万。

明らかに、実際にはこれらの制限に遭遇することは決してありません。心配しないでください。

42
Eric Lippert

実装できるインターフェースの数は、コンパイラーが処理できるものによって制限されます。インターフェイスが多すぎると、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());
15
Tim Lloyd

多くのインターフェースを実際に実装することを目的としてこの質問をしているのであれば、深刻な設計上の問題があると思います。

私の知る限り、コンピュータのメモリ以外に制限はありません。

8
Nobody

MicrosoftC♯言語仕様バージョン4.0の現在のバージョンを確認しましたが、§1.6.4、§1.9、§10.1.4、§10.1.4.2、および§13に制限についての言及はありません。 §B.2.7の文法にも構文上の制限はありません。

私は明らかに500ページ全体を読んだわけではありませんが、そのドキュメントの他のどこに制限が記載されているのかわかりません。

注:これはMicrosoftC♯にのみ適用され、バージョン4.0にのみ適用されます。以前のバージョンのMicrosoftC♯もチェックしませんでした。ECMA/ISOC♯もチェックしませんでした。また、C♯にのみ適用され、CLIに制限がある場合があります。

最後になりましたが、MicrosoftVisualC♯とNovellMonoC♯の両方に実装固有の制限があり、MicrosoftとMonoのCLIの実装(CLRとMono VM)にも実装固有の制限がある可能性があります。

ただし、質問はC♯に関するものであり、C♯の特定の実装やCLIに関するものではないため、クラスが実装できるインターフェイスの数に制限はないと主張することにかなり自信を持っています。

1
Jörg W Mittag

MyClass: IInteferface_1, IInterface_2, ... , IInterface_Nと言うことは、コンパイラー/ランタイムにとって実際に何を意味するのかを考えてください。コンパイラは、実装する予定の各インターフェイスに適切な(メソッド)シグネチャがあることをコンパイラが確認するだけなので、設計時間の制限はありません。実行時間の制限に関しては、(設計時に検証された)実装するインターフェイスを介したクラスへの参照は、クラスがそのインターフェイスに適切なメソッドシグネチャを持っていることを確認するだけなので、メモリはあまり影響を与えないと思います。オブジェクトがインターフェイスを実装していない場合、オブジェクトにはメソッドシグネチャがないだけです。

1
bitxwise