25

C# の場合:

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

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

Nに制限はありますか?

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

4

6 に答える 6

45

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

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

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

明らかに、実際にこれらの制限に遭遇することはありません。ご心配なく。

于 2010-11-26T16:11:36.203 に答える
15

実装できるインターフェイスの数は、コンパイラが処理できるものによって制限されます。インターフェイスが多すぎると、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());
于 2010-11-26T15:42:07.360 に答える
8

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

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

于 2010-11-26T13:18:16.397 に答える
1

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♯ と Novell Mono C♯ の両方に実装固有の制限があり、Microsoft と Mono の CLI の実装 (つまり、CLR と Mono VM) にも実装固有の制限がある可能性があります。

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

于 2010-11-26T15:33:14.137 に答える
1

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

于 2010-11-26T13:57:35.427 に答える
-7

限界があります

関連するインターフェイスの型テーブルへの JIT によって 1 バイトがインデクサーとして使用されるため、255 に制限されます。

于 2010-11-26T13:32:42.070 に答える